Skip to main content

Overview

Flowglad tracks feature entitlements and consumption so you can gate premium functionality or enforce usage-based 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 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

'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>
    )
  }

Example: Usage Balance Check

'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>
  )
}

Example: Recording Usage

'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>
}