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

# Entitlements

> How plan versions become customer access decisions.

Entitlements are the customer's feature access and limits. Your app checks them before paid work
runs, and Unprice keeps the decision tied to plan-version, usage, wallet, and invoice evidence.

## The entitlement flow

1. A customer signs up for a published plan version.
2. Unprice derives the customer's entitlements from that plan version.
3. Your app calls `access.check` or `usage.consume` before paid work runs.
4. Accepted usage keeps evidence for usage, spend, wallet, and invoice explanation.

## Features vs. entitlements

| Concept     | Meaning                                       | Example                                     |
| ----------- | --------------------------------------------- | ------------------------------------------- |
| Feature     | What your team sells or gates                 | `ai-messages`, `ai-generations`, `ai-tools` |
| Entitlement | What the customer can use from a plan version | 10,000 AI messages this month               |
| Meter       | How usage events become a period total        | sum `aiMessages` from `completions` events  |

Features are authored by your team. Entitlements are the customer-specific rights and limits created
from a published plan version.

## Check access

Use `access.check` when you want a read-only decision.

```ts theme={null}
const { result, error } = await unprice.access.check({
  customerId: "cus_1234567890",
  featureSlug: "ai-messages"
});

if (error) {
  throw new Error(error.message);
}

if (!result.allowed) {
  return new Response("Feature unavailable", { status: 403 });
}
```

This is the safest first integration because it mutates nothing. Run it in shadow beside your
current logic before enforcing.

## Consume usage

Use `usage.consume` when the request path needs a synchronous decision and the usage amount is
known.

```ts theme={null}
const { result, error } = await unprice.usage.consume({
  customerId: "cus_1234567890",
  featureSlug: "ai-messages",
  eventSlug: "completions",
  idempotencyKey: "req_123",
  properties: {
    aiMessages: 1,
    inputTokens: 1840,
    outputTokens: 620
  }
});

if (error) {
  throw new Error(error.message);
}

if (!result.allowed) {
  return new Response("Usage limit reached", { status: 429 });
}
```

`usage.consume` is an enforcing operation. Use [Choose the runtime call](/quickstart/choose-operation)
to decide when to use `access.check`, `usage.record`, `usage.consume`, or budgeted runs.

## Why this matters

Your app should not branch on plan names such as `Pro` or `Enterprise`. It should check stable
feature slugs and let Unprice resolve the customer's plan version, entitlement, usage, budget, and
wallet state.
