> For the complete documentation index, see [llms.txt](https://decentralabs-2.gitbook.io/decentralabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://decentralabs-2.gitbook.io/decentralabs-docs/smart-contracts/concepts/reservations.md).

# Reservations

## Scope and identifiers

The production Diamond exposes institutional reservation write paths. The older generic request, confirmation and cancellation selectors are explicitly forbidden by `selectors/diamond.json`; consumers should not build new flows on them.

A reservation stores lab, renter/tracking identity, payer and collector institutions, price, provider share, timestamps and lifecycle status. For a paid reservation, the platform commission is 40% by default and the provider share is 60%; an approved per-lab agreement can change that split. See [Service credits and settlement](/decentralabs-docs/smart-contracts/concepts/credits-and-settlement.md) for the commission and fixed-fee rules. For institutional paths the public reservation key is derived from `labId`, `start` and the PUC hash. It identifies the currently occupied slot. Every accepted request also receives a unique immutable `reservationId`; credit allocations, expiry, spending-period markers, sessions, payout heaps and historical snapshots use that generation id so a cancelled slot can be reused safely. Use `getReservationId` and `getReservationById` for generation-aware reads.

## Lifecycle

```mermaid
stateDiagram-v2
    [*] --> PENDING: request
    PENDING --> CONFIRMED: confirmation and treasury charge
    PENDING --> CANCELLED: denial, cancellation or request expiry
    CONFIRMED --> ACCESS_AUTHORIZED: check-in
    CONFIRMED --> SETTLED: finalization after end
    CONFIRMED --> CANCELLED: eligible pre-start cancellation
    ACCESS_AUTHORIZED --> SETTLED: finalization
    CANCELLED --> [*]
    SETTLED --> [*]
```

| Value | Status              | Meaning                                                                 |
| ----: | ------------------- | ----------------------------------------------------------------------- |
|   `0` | `PENDING`           | Request exists; it does not occupy the active calendar.                 |
|   `1` | `CONFIRMED`         | Booking has passed provider and treasury checks and is active.          |
|   `2` | `ACCESS_AUTHORIZED` | On-chain access was authorized; this is not proof of a started session. |
|   `3` | `SETTLED`           | Finalization cleaned active indexes and applied the economic outcome.   |
|   `4` | `CANCELLED`         | Request or booking was cancelled and cleaned from active indexes.       |

## Request and confirmation

An institution wallet or its authorized backend creates a request with a non-zero PUC hash, an existing lab and a valid time range. The intent-bound organization must resolve on-chain to that institution; the backend is only the transaction executor and is never stored as the payer. Validation enforces the request TTL (five minutes in the current source configuration), a ten-minute minimum lead time before the reservation starts, the lab's booking rules and the institutional user's policy. The lead time is shared by Marketplace and the contract so direct institutional backends cannot create a request with only a few seconds for provider confirmation. A pending request can be denied by the eligible provider side, cancelled through the institutional path, or released after its TTL.

External-request confirmation may be submitted only by the current lab owner or its authorized backend. It checks the PUC binding, provider network status, listing and stop-intake state. It then captures the payer institution's applicable treasury charge and spending-period context; the economic rules for priced and zero-priced bookings are summarized in [Service credits and settlement](/decentralabs-docs/smart-contracts/concepts/credits-and-settlement.md).

A same-institution own-lab intent can atomically request and confirm through the direct-booking path. The current lab owner or its authorized backend may execute that path, while the owner remains the payer/provider identity. It is a separate payer-authorized flow implemented by `institutionalDirectBookingWithIntent`, not by a direct administrative selector. All same-institution own-lab reservations have zero lab price and incur the fixed four-credit booking fee on confirmation.

The effective decision deadline for a pending request is the earlier of its five-minute request TTL and `reservation.start`. The ten-minute creation lead leaves a five-minute safety margin after the decision window. The canonical backend keeps 12-confirmation event finality, but shortens fallback polling and retry delays to 15 seconds; if finality or provider processing does not complete before the deadline, the request expires without confirmation or credit capture. Deployments that raise confirmation depth or polling latency must increase the TTL and lead time in a reviewed Diamond upgrade before rollout. Confirmation at `start`, after `start`, or after `end` cancels the pending request as expired and does not capture credits. The same deadline is used when a pending request is released or when its slot is reused after expiry. A pending request does not occupy the calendar, but it remains a lab obligation and therefore blocks lab deletion until it is confirmed or reaches a terminal state.

These timing values are embedded in the deployed reservation facets. Updating the source constants alone does not change an existing Diamond; verify the reviewed upgrade and live selectors before enabling the corresponding provider configuration.

There is no direct institution/backend reservation selector in the production surface. External requests use `institutionalReservationRequestWithIntent` and own-lab bookings use `institutionalDirectBookingWithIntent`; both consume the corresponding intent before creating state. WebAuthn remains an off-chain backend control and is not verified by the Diamond.

Existing deployments require a reviewed `diamondCut` that removes the retired selector. Updating the source manifest and ABI does not change live Diamond routing by itself.

Confirmation inserts an exclusive (`resourceType = 0`) range into the interval calendar, queues the reservation for later settlement, and stores the provider share. See [Service credits and settlement](/decentralabs-docs/smart-contracts/concepts/credits-and-settlement.md) for the provider/platform split and the distinct fixed-charge rules. A concurrent FMU resource (`resourceType = 1`) uses the same lifecycle without the exclusive-calendar conflict path and records active reservations in the concurrency index. The Diamond does not store or enforce a per-lab concurrent-user limit: overlapping FMU confirmations are valid on-chain, and `getConcurrentReservationCount` is a read-only occupancy query rather than an authorization primitive.

The concurrent-user policy is provider-owned and off-chain. The provider's lab metadata declares `maxConcurrentUsers`; the canonical provider backend reads the overlapping on-chain count, validates that declaration and the effective station capacity, and serializes the decision with a shared MySQL advisory lock before submitting the provider confirmation. An invalid or missing `maxConcurrentUsers` declaration is a provider-policy rejection; unavailable metadata, station-capacity or lock infrastructure leaves provider processing retryable. A caller with on-chain provider confirmation authority that bypasses this backend can therefore create overlapping FMU reservations without the provider's metadata limit.

## Finalization and queries

`releaseInstitutionalExpiredReservations` is permissionless and bounded by a maximum batch of 50 records. It finalizes:

* confirmed reservations after their end; and
* access-authorized reservations after their end when SessionStarted evidence exists, or after the session-attestation deadline otherwise.

Finalization removes calendar, lab, renter and institutional-user indexes as one operation. When valid session evidence is present, it accrues the provider share. For a physical lab without it, the no-show settlement retains exactly 25% of the reservation price. It refunds the remaining 75% and keeps the existing 15% provider / 10% implicit platform split. A simulation without evidence is refunded in full.

The same economic deadline is also enforced by the bounded cleanup performed while validating a new request for a user near the per-lab reservation cap. That cleanup cannot settle an `ACCESS_AUTHORIZED` reservation without `SessionStarted` evidence until `end + 1 day`; a delayed attestation therefore cannot be invalidated by requesting another reservation. Permissionless release, cap cleanup and provider payout all delegate their terminal transition to the same `LibInstitutionalReservationSettlement` path.

`finalizeEligibleReservations(labId, maxBatch)` is the permissionless maintenance entry point for confirmed/access-authorized reservations already present in the payout heap. It accepts at most 10 bounded attempts, returns the number finalized, and emits `ReservationFinalizationBatchProcessed`. A caller only pays gas: the function never queues provider receivable, approves a settlement or pays the caller. A call with no eligible candidate is a successful no-op. The existing `requestProviderPayout` authorization and its transition from accrued receivable to settlement queue are unchanged.

The selector belongs to the dedicated `ReservationFinalizationFacet`, not to `ProviderSettlementFacet`. An upgrade must therefore add the new facet and replace the changed lab/settlement facets in the same coordinated `diamondCut`.

`getLabFinalizationStatus(labId)` exposes bounded maintenance signals: `activeReservationCount`, payout-heap length, the number of invalid lazy heap entries, the heap-root candidate end timestamp and `lastFinalizationAt`. The heap root is only a candidate hint; it is not an unbounded eligibility scan. The active counters are stored on-chain and are decremented by finalization; they are not recalculated automatically when a reservation's `end` timestamp passes.

Use `getReservation`, availability reads and the paginated institutional/query functions for state inspection. Do not infer availability from a pending request or from off-chain calendar data.

## Cancellation and denial

The normal institutional cancellation path is limited to a confirmed booking before its start time and requires the configured backend plus the matching PUC hash. The direct selectors `cancelInstitutionalReservationRequest` and `cancelInstitutionalBookingWithPucHash` are backend-only; the institution wallet is not an alternate executor. See [Service credits and settlement](/decentralabs-docs/smart-contracts/concepts/credits-and-settlement.md) for the current fee, refund and provider-reputation outcomes. A provider-side cancellation is separate: the current provider or its authorized backend must provide a non-zero reason code. The service-failure reason is allowed only for a confirmed or access-authorized reservation while the attestation grace period is open and when `SessionStarted` has not been recorded; an ordinary payer no-show is not itself provider misconduct.

For a pending external request, only the current ERC-721 lab owner or the backend currently authorized by that owner may deny. The payer institution and its backend may cancel their own pending request, but they cannot deny it or turn it into a confirmed external booking. Own-lab `DIRECT_BOOKING` is the explicit atomic exception because the payer and provider are the same institution.

`previewInstitutionalBookingCancellation` returns the contract's current summary before a transaction: status, eligibility, refund destination, fees, cutoff, period data, source-credit expiry and policy version. Its allocations array is intentionally empty so the read remains bounded. Query source-lot provenance with `getCreditReservationAllocations` using pagination; use `offset=0, limit=0` for the count only. Use the preview for confirmation UI rather than duplicating fee logic. `sourceCreditExpiry` is informational and does not add a cancellation gate: eligibility is determined by the confirmed status and the current block timestamp being before the cancellation cutoff.
