Documentation
Everything you need to know about building with the SaaS Starter Kit
Getting Started
1. Clone and Install
npm install2. Set Up Environment Variables
Copy .env.example to .env and fill in your credentials:
3. Initialize Database
Authentication
Setup
Sign up at clerk.com and get your API keys
Protected Routes
Routes are protected using middleware. All /dashboard routes require authentication.
// middleware.ts
export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect()
})Get Current User
import { getCurrentUser } from '@/lib/clerk-helpers'
const user = await getCurrentUser()Webhooks
User data is automatically synced to your database via Clerk webhooks at /api/webhooks/clerk
Database
Schema
The database schema includes User, Subscription, and Usage models:
model User {
id String @id @default(cuid())
clerkId String @unique
email String @unique
name String?
subscription Subscription?
usage Usage[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Queries
import { prisma } from '@/lib/prisma'
const user = await prisma.user.findUnique({
where: { clerkId: userId },
include: { subscription: true }
})Helper Functions
Use the helper functions in lib/db-helpers.ts for common operations like getting user data, checking subscription status, and tracking usage.
Billing
Setup
- Create a Stripe account and get your API keys
- Create products and prices in Stripe Dashboard
- Add price IDs to your environment variables
- Configure webhook endpoint at
/api/webhooks/stripe
Create Checkout Session
const response = await fetch('/api/stripe/create-checkout-session', {
method: 'POST',
body: JSON.stringify({ priceId: 'price_xxx' })
})Customer Portal
Users can manage their subscriptions through the Stripe Customer Portal, accessible from the billing page.
Webhooks
Subscription events are automatically handled via webhooks, updating your database when subscriptions are created, updated, or cancelled.
API Routes
Available Endpoints
GET /api/userGet current userPATCH /api/userUpdate user profileGET /api/usageGet user usage dataPOST /api/usageTrack usage eventGET /api/subscriptionGet subscription infoGET /api/analyticsGet analytics dataPOST /api/stripe/create-checkout-sessionCreate checkout sessionPOST /api/stripe/create-portal-sessionCreate customer portal sessionPOST /api/webhooks/clerkClerk user sync webhookPOST /api/webhooks/stripeStripe subscription webhookRate Limiting
API routes include rate limiting to prevent abuse:
import { rateLimit } from '@/lib/rate-limit'
const limiter = rateLimit({ interval: 60000, uniqueTokenPerInterval: 500 })
await limiter.check(10, userId)Client Usage
Use the API client helper for type-safe requests:
import { apiClient } from '@/lib/api-client'
const data = await apiClient.get('/api/user')Webhooks Setup
- Go to Clerk Dashboard → Webhooks
- Add endpoint:
https://your-domain.com/api/webhooks/clerk - Subscribe to:
user.created,user.updated,user.deleted - Copy webhook secret to
CLERK_WEBHOOK_SECRET
- Go to Stripe Dashboard → Developers → Webhooks
- Add endpoint:
https://your-domain.com/api/webhooks/stripe - Subscribe to:
checkout.session.completed,invoice.payment_succeeded,customer.subscription.updated,customer.subscription.deleted - Copy webhook secret to
STRIPE_WEBHOOK_SECRET
Deployment
Steps
- Push your code to GitHub
- Import your repository on Vercel
- Add environment variables
- Deploy
Environment Variables
Make sure to add all required environment variables from .env.example to your Vercel project settings.
Webhooks
Update your webhook URLs in Clerk and Stripe dashboards to point to your production domain.