SaaS applications need to restrict feature access based on subscription plan without leaking business logic to the client. Clerk provides billing subscription APIs and organization management that let you safely enforce plan-based feature gates server-side. Use Clerk's billing endpoints to fetch active subscription data and compare against feature allowlists on the backend. Combine organization subscription queries with role-based checks to implement hierarchical, audit-safe feature gating.
What this tutorial covers
- •Outcome: You will query Clerk's billing and organization APIs to gate features server-side, preventing unauthorized tier downgrades and pricing logic bypasses.
- •Endpoints used: `GET /organizations/{organization_id}/billing/subscription`
- •SDK methods: `getOrganizationBillingSubscription()`
- •Language: typescript
- •Auth: API key (Authorization header with Bearer token)
- •Estimated implementation time: ~15 minutes
Step 1: Fetch organization subscription data from Clerk
Retrieve the active subscription tier for an organization using Clerk's billing subscription endpoint. This server-side call ensures pricing data cannot be manipulated by client code.
Query subscription status
1import { clerkClient } from '@clerk/nextjs/server';
2
3async function getOrgSubscriptionTier(organizationId: string) {
4 const subscription = await clerkClient.billing.getOrganizationBillingSubscription(organizationId);
5 return subscription;
6}
7
8async function fetchActiveSubscription(orgId: string) {
9 try {
10 const subscriptionData = await clerkClient.billing.getOrganizationBillingSubscription(orgId);
11 console.log('Organization subscription tier:', subscriptionData);
12 return subscriptionData;
13 } catch (error) {
14 console.error('Failed to fetch subscription data:', error);
15 throw error;
16 }
17}Response:
1// Fetch organization subscription data from Clerk
2const organizationId = 'org_123'
3
4const subscription = await clerkClient.billing.getOrganizationBillingSubscription(organizationId)
5
6// Response shape: BillingSubscription
7// (Type definition from Clerk SDK — exact field names depend on BillingSubscription interface)
8// Common fields typically include subscription ID, plan reference, status, and billing period datesStep 2: Map plan IDs to feature allowlists in Clerk middleware
Create a feature-gate layer that maps Clerk plan IDs to enabled features, keeping pricing logic separate from application code. This centralized approach simplifies pricing changes and prevents feature-access bugs.
Define feature allowlist mapping
The mapping isolates plan tier logic from feature checks, making it safe to update pricing without touching application code.
Step 3: Check feature access before serving protected endpoints
In your API route or server action, verify the organization's subscription status and check the requested feature against the allowlist. Combine Clerk's organization context with the feature gate to block unauthorized access at request time.
Enforce feature gate in middleware
Calls to protected features are rejected unless the organization holds an active subscription with the feature in its allowlist.
Step 4: Protect API routes with Clerk billing checks
Use the feature-gate function to wrap server endpoints and API routes, preventing plan-downgrade exploits. Return 402 Payment Required or 403 Forbidden for tier mismatches, signaling client-side upsell UI.
Secure Next.js API route
The API rejects calls from organizations without the required plan tier, preventing unauthorized usage and enforcing billing boundaries.
Step 5: Handle subscription state transitions in Clerk webhooks
Listen to Clerk organization.subscription.* webhook events to sync plan changes and invalidate cached feature gates. Real-time sync ensures users see billing updates immediately and cannot exploit stale subscription data.
Process subscription event webhooks
Webhooks ensure your feature gates reflect the latest subscription state, eliminating race conditions and stale-cache exploits.
Common pitfalls when using Clerk
- •Client-side feature checks are not secure. Never gate features solely on the client; users can disable JavaScript or modify network responses. Always validate subscription and feature access on the server before processing sensitive operations.
- •Caching subscription data without TTL. Webhook delays or network outages can cause cached subscription status to drift from Clerk's source of truth. Set a short TTL (e.g., 5–10 minutes) and always re-check on critical operations.
- •Mixing plan logic into authorization code. Embedding subscription tiers directly into role definitions (e.g., 'pro_admin') makes pricing changes risky. Keep RBAC (owner, admin, member) separate from plan-based feature gates using a dedicated feature-gate layer.
- •Denying access on billing API failures. If Clerk's billing endpoint is slow or temporarily unavailable, always deny access rather than allowing it; this prevents privilege escalation but may frustrate users. Implement graceful degradation and monitor Clerk's status.
Ready to ship secure, plan-based feature gating? Get started with Clerk's billing and organization APIs today.
Documentation references
The code examples in this tutorial are grounded in the following docs pages:
- •
- •
Want seamless auth for your next app?
Join leading teams using Clerk’s authentication platform to accelerate launches, scale securely, and delight users from day one.

