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

# Feature Access & Usage

> Check entitlements and usage balances with Flowglad

## Overview

Flowglad tracks feature entitlements and consumption so you can gate premium functionality or enforce [usage-based](/features/usage) plans. Use `checkFeatureAccess` for toggle features, or `checkUsageBalance` and `createUsageEvent` for usage-based features. Learn how to validate access before rendering protected experiences.

### How to use

* For `checkFeatureAccess` (available on client & server): provide the `featureSlug` to check for and optionally refine the result to a specific subscription by passing in a `subscriptionId` for `refinementParams`. Returns a boolean.
* For `checkUsageBalance` (available on client & server): provide the `usageMeterSlug` to check for and optionally refine the result to a specific subscription by passing in a `subscriptionId` for `refinementParams`. Returns either `{ availableBalance: number }` or `null` if not found.
* For `createUsageEvent` (available on client & server): provide exactly one of `priceSlug`, `priceId`, `usageMeterSlug`, or `usageMeterId` to identify the usage price. Using `usageMeterSlug` or `usageMeterId` resolves to the meter's default price. All events will have a `priceId` in the response.
  * **Client**: The SDK auto-resolves `subscriptionId` from the current subscription, defaults `amount` to 1, and auto-generates `transactionId` for idempotency. You can optionally override any of these.
  * **Server**: You must provide `subscriptionId`, `transactionId`, and `amount` explicitly, along with optional `properties` and `usageDate`.
    The optional `properties` field is for usage meters with count distinct aggregation type. See [here](/api-reference/usage-events/create-usage-event#body-usage-event) for more details on the parameters.

### What you can do

* Query customer's feature access using the client or server SDK
* Fetch usage balances for metered features and display remaining quota.
* Combine entitlement checks with subscription state for robust authorization logic

### Example: Feature Access Check

<Tabs>
  <Tab title="Client">
    ```tsx theme={null}
    'use client'

    import { useBilling } from '@flowglad/nextjs'

    export function FeatureAccessGate({
      featureSlug,
    }: {
      featureSlug: string
    }) {
        const {
          loaded,
          errors,
          checkFeatureAccess,
        } = useBilling()

        if (!loaded || !checkFeatureAccess) {
          return <p>Loading billing state…</p>
        }

        if (errors) {
          return <p>Unable to load billing data right now.</p>
        }

        return (
          <div>
            <h3>Feature Access</h3>
            {checkFeatureAccess(featureSlug) ? (
              <p>You can use this feature ✨</p>
            ) : (
              <p>You need to upgrade to unlock this feature.</p>
            )}
          </div>
        )
      }
    ```
  </Tab>

  <Tab title="Server">
    ```ts theme={null}
    import { NextResponse } from 'next/server'
    import { flowglad } from '@/utils/flowglad'

    // How to use checkFeatureAccess on the backend:
    export async function GET(request: Request) {
      const { searchParams } = new URL(request.url)
      const featureSlug = searchParams.get('featureSlug') ?? 'ai-copilot'
      // Extract customerExternalId from your auth/session
      // This should be YOUR app's user/organization ID, NOT Flowglad's customer ID
      const userId = await getUserIdFromRequest(request)

      const billing = await flowglad(userId).getBilling()
      const hasAccess = billing.checkFeatureAccess(featureSlug)

      return NextResponse.json({ featureSlug, hasAccess })
    }
    ```
  </Tab>
</Tabs>

### Example: Usage Balance Check

<Tabs>
  <Tab title="Client">
    ```tsx theme={null}
    'use client'

    import { useBilling } from '@flowglad/nextjs'

    export function UsageBalanceIndicator({
      usageMeterSlug,
    }: {
      usageMeterSlug: string
    }) {
      const {
        loaded,
        errors,
        checkUsageBalance,
      } = useBilling()

      if (!loaded || !checkUsageBalance) {
        return <p>Loading usage…</p>
      }

      if (errors) {
        return <p>Unable to load billing data right now.</p>
      }

      const usage = checkUsageBalance(usageMeterSlug)

      return (
        <div>
          <h3>Usage Balance</h3>
          <p>
            Remaining:{' '}
            {usage ? `${usage.availableBalance} credits` : 'No usage meter found'}
          </p>
        </div>
      )
    }
    ```
  </Tab>

  <Tab title="Server">
    ```ts theme={null}
    import { NextResponse } from 'next/server'
    import { flowglad } from '@/utils/flowglad'

    export async function GET(request: Request) {
      const { searchParams } = new URL(request.url)
      const usageMeterSlug = searchParams.get('usageMeterSlug') ?? 'api-calls'
      // Extract customerExternalId from your auth/session
      // This should be YOUR app's user/organization ID, NOT Flowglad's customer ID
      const userId = await getUserIdFromRequest(request)

      const billing = await flowglad(userId).getBilling()
      const usage = billing.checkUsageBalance(usageMeterSlug)

      return NextResponse.json({
        usageMeterSlug,
        remaining: usage?.availableBalance ?? null,
      })
    }
    ```
  </Tab>
</Tabs>

### Example: Recording Usage

<Tabs>
  <Tab title="Client">
    ```tsx theme={null}
    'use client'

    import { useBilling } from '@flowglad/nextjs'

    export function RecordUsageButton({
      usageMeterSlug,
    }: {
      usageMeterSlug: string
    }) {
      const billing = useBilling()

      const handleClick = async () => {
        if (!billing.createUsageEvent) return

        const result = await billing.createUsageEvent({
          usageMeterSlug,
          amount: 1, // optional, defaults to 1
        })

        if ('error' in result) {
          console.error('Failed to record usage:', result.error)
          return
        }

        console.log('Usage recorded:', result.usageEvent.id)
      }

      return <button onClick={handleClick}>Use Feature</button>
    }
    ```
  </Tab>

  <Tab title="Server">
    ```ts theme={null}
    import Fastify from 'fastify'
    import { type CreateUsageEventParams } from '@flowglad/server'
    import { flowglad } from '@/utils/flowglad'

    const fastify = Fastify()

    fastify.post('/api/usage', async (request, reply) => {
      const {
        amount,
        priceSlug, // or priceId, usageMeterSlug, usageMeterId (exactly one required)
        subscriptionId,
        transactionId,
        usageDate,
        properties,
      } = request.body as CreateUsageEventParams
      // Extract customerExternalId from your auth/session
      // This should be YOUR app's user/organization ID, NOT Flowglad's customer ID
      const userId = await getUserIdFromRequest(request)

      const usageEvent = await flowglad(userId).createUsageEvent({
        amount,
        priceSlug, // or priceId, usageMeterSlug, usageMeterId
        subscriptionId,
        transactionId,
        usageDate: usageDate ?? Date.now(),
        properties,
      })

      reply.send({ usageEvent })
    })

    fastify.listen({ port: 3000 })
    ```
  </Tab>
</Tabs>
