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

# Entitlements

> Check if a tenant has access to a feature based on their active plan.

**Entitlements** are how Crovver determines whether a tenant can access a specific feature. Crovver checks the tenant's active subscription and looks up the feature in the plan's `features` map.

## How It Works

When you call `canAccess`:

1. Crovver looks up the tenant's active subscription
2. Fetches the associated plan
3. Checks `plan.features[featureKey] === true`
4. Returns `canAccess: true` or `false`

No active subscription → `canAccess: false`.
Subscription in `past_due` → `canAccess: false`.
Subscription in `trial` → `canAccess: true` (trial counts as active).

## Checking Access — Frontend

Use the `useFeatureAccess` hook:

```tsx theme={null}
import { useFeatureAccess } from 'crovver-react';

function ExportButton() {
  const { hasAccess, redirectToUpgrade } = useFeatureAccess('data_export');

  if (!hasAccess) {
    return <button onClick={redirectToUpgrade}>Upgrade to Export</button>;
  }

  return <button onClick={exportData}>Export</button>;
}
```

## Checking Access — API

```bash theme={null}
GET /api/public/can-access?publicKey=pk_live_...&featureKey=data_export&requestingEntityId=workspace_123
```

```json theme={null}
{
  "success": true,
  "data": {
    "canAccess": true,
    "featureKey": "data_export",
    "requestingEntityId": "workspace_123"
  }
}
```

## Blocking UI with FeatureGuard

The `<FeatureGuard>` component handles the gate declaratively:

```tsx theme={null}
import { FeatureGuard } from 'crovver-react';

<FeatureGuard
  featureKey="advanced_analytics"
  fallback={<UpgradePrompt />}
>
  <AnalyticsDashboard />
</FeatureGuard>
```

## Metered / Credit-Based Limits

Entitlements handle boolean feature access. For **consumable resources** (API calls, AI tokens, SMS credits), use the credit pool system instead:

1. **Check balance** before the action — [`GET /api/public/credits/balance`](/api-reference/credits/balance)
2. **Consume credits** after the action — [`POST /api/credits/consume`](/api-reference/credits/consume) (idempotent)

```bash theme={null}
# 1. Read balance
GET /api/public/credits/balance?tenantId=workspace_123

# 2. Consume
POST /api/credits/consume
{
  "tenantId": "workspace_123",
  "poolKey": "api_calls",
  "amount": 1,
  "idempotencyKey": "consume-1778423112701"
}
```

See [Credits & Credit Pools](/concepts/credits) for the full model.
