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

# Lease-Based Revocation

> Revoke a viewer's access without re-encrypting content using time-limited leases that the player renews automatically.

Leases let you revoke a viewer's access to content **without re-encrypting the video**. When enabled, the player acquires a time-limited lease from the key server and renews it automatically. If the lease is revoked server-side, the player stops playback and emits an error.

## Enable leases

```typescript theme={null}
import { createPlayer } from "@blindcast/player"

const result = createPlayer(videoEl, {
  keyServerUrl: "https://keys.example.com/keys",
  keyServerAuth: async () => getAccessToken(),
  lease: {
    leaseEndpoint: "https://keys.example.com/keys",
    requestedTtlMs: 10 * 60 * 1000, // request a 10-minute lease
  },
})
```

## How it works

1. When `player.load()` is called, the player requests a lease from the lease endpoint
2. The server returns a lease ID and a TTL (which may be shorter than requested)
3. The player sends the lease ID as an `X-Lease-Id` header on every key request
4. At 75% of the TTL, the player proactively renews the lease
5. If the server revokes the lease, the next key request or renewal fails with 403
6. The player emits `KEY_LEASE_EXPIRED` and stops playback

## Handle revocation

```typescript theme={null}
player.on("error", (err) => {
  if (err.code === "KEY_LEASE_EXPIRED") {
    // Lease was revoked — show "access ended" UI
    showAccessRevokedMessage()
    player.destroy()
  }
})
```

## Lease options

| Option               | Type     | Default           | Description                                          |
| -------------------- | -------- | ----------------- | ---------------------------------------------------- |
| `leaseEndpoint`      | `string` | *(required)*      | Base URL of the lease endpoint                       |
| `requestedTtlMs`     | `number` | `300_000` (5 min) | TTL to request. Server may return a shorter TTL.     |
| `renewalFraction`    | `number` | `0.75`            | Fraction of TTL at which to trigger renewal (0–1)    |
| `minRenewalBufferMs` | `number` | `30_000`          | Minimum renewal buffer in ms, regardless of fraction |

## When to use leases

* **Subscription content:** Revoke access when a user cancels their subscription
* **Time-limited previews:** Allow 5 minutes of free playback, then revoke
* **Concurrent stream limits:** Revoke the oldest session when the limit is exceeded
* **Content takedowns:** Immediately stop all active playback of removed content

See [Key Server Leases](/key-server/leases) for server-side setup.
