Best Boilerplates for API Products 2026
API Products Are a Distinct SaaS Model
An API product sells programmatic access — not a UI, not a workflow, not an app. The customer is a developer or a company that integrates your service into their own product. Stripe, Twilio, SendGrid, and OpenAI are API products at scale.
Building an API product in 2026 means:
- Selling access (credits, subscriptions, or metered usage)
- Providing a developer portal with documentation and API key management
- Delivering reliability, uptime, and consistent response formats
- Handling authentication, rate limiting, and usage tracking at every request
The boilerplates below handle the business layer. You provide the API logic.
TL;DR
Best boilerplates for API products in 2026:
- Makerkit ($299) — Only boilerplate with native Stripe Meters (usage-based billing). Required for true pay-per-use APIs.
- Midday v1 (free) — Production-grade architecture, background jobs, rate limiting (Upstash). Best technical foundation.
- OpenSaaS (free) — Background jobs, Stripe billing, admin dashboard. Best free complete option.
- T3 Stack (free) — TypeScript-first, developer audience credibility, clean API design patterns.
- ShipFast ($199) — Fastest to launch. Manual billing additions required.
Key Takeaways
- Usage-based billing (Stripe Meters) is the dominant model for API products — only Makerkit supports it natively
- API key management is not included in most boilerplates — add it in ~2 hours with the pattern below
- Rate limiting per key requires Upstash Redis — Midday v1 includes this
- Webhooks (Svix) are a common requirement for event-driven API products
- OpenAPI spec generation (via Hono or Scalar) enables auto-generated client SDKs
- The average API product needs ~40 hours of custom work on top of any boilerplate
The API Product Architecture
API Gateway Layer:
- Authentication (API key validation)
- Rate limiting (per key, per tier)
- Usage tracking (events per key)
- Request logging
Business Logic Layer:
- Your core API endpoints
- Background processing for async operations
- Webhook delivery for events
Billing Layer:
- Usage metering (Stripe Meters or custom counters)
- Credit balance management
- Invoice generation
Developer Portal:
- API key generation/revocation
- Usage dashboard (requests, errors, latency)
- Documentation
- Webhook management
Boilerplate Analysis
Makerkit: Best for Monetization
Makerkit is the only SaaS boilerplate with native Stripe Meters support — the Stripe feature for metering usage and billing at end of period.
// Makerkit usage-based billing pattern:
import { createStripeClient } from '@makerkit/billing-stripe';
const stripe = createStripeClient();
// Report API usage (called after each successful API call):
await stripe.billing.meterEvents.create({
event_name: 'api_call',
payload: {
stripe_customer_id: account.stripeCustomerId,
value: '1',
},
});
Makerkit also includes:
- Multi-seat team billing — companies buy seats, individual members call the API
- Per-plan limits — different rate limits and credit amounts per subscription tier
- Admin dashboard — monitor usage, manage accounts, handle billing issues
Limitation: Makerkit targets Next.js/React apps. If your API has no web UI, you are paying for features you do not use.
Midday v1: Best Technical Foundation
Midday's architecture maps well to API products:
- Upstash rate limiting is built-in — per-user and per-endpoint
- Trigger.dev background jobs handle async API operations (image processing, data pipelines, LLM chains)
- Supabase provides a robust database with row-level security for multi-tenant API data
- Sentry error tracking is configured from day one
Missing: billing, API key management, developer portal. All addable.
T3 Stack: Best Developer DX
For API products targeting developers, T3 Stack provides:
- tRPC — type-safe API with automatic client generation
- TypeScript throughout — no runtime type errors
- Clean codebase that holds up to customer due diligence
The trade-off: no billing, no auth providers (add Clerk), no admin dashboard. But developer buyers will inspect your GitHub repo, and T3 Stack code inspires more confidence than a rushed ShipFast fork.
Critical Infrastructure: API Keys
// lib/api-keys.ts — copy this pattern into any boilerplate:
import { db } from './db';
import { createHash, randomBytes } from 'crypto';
export interface ApiKey {
id: string;
userId: string;
name: string;
prefix: string; // Displayed in dashboard: "sk_live_abc123..."
hashedKey: string;
createdAt: Date;
lastUsedAt: Date | null;
revokedAt: Date | null;
expiresAt: Date | null;
}
export async function createApiKey(userId: string, name: string): Promise<string> {
const rawKey = `sk_live_${randomBytes(32).toString('hex')}`;
const hashedKey = createHash('sha256').update(rawKey).digest('hex');
const prefix = `${rawKey.slice(0, 15)}...`;
await db.apiKey.create({
data: { userId, name, prefix, hashedKey },
});
// Return raw key only once — not stored in DB
return rawKey;
}
export async function validateKey(rawKey: string): Promise<ApiKey | null> {
if (!rawKey?.startsWith('sk_live_')) return null;
const hashedKey = createHash('sha256').update(rawKey).digest('hex');
const key = await db.apiKey.findUnique({ where: { hashedKey } });
if (!key || key.revokedAt || (key.expiresAt && key.expiresAt < new Date())) {
return null;
}
// Async last-used update (don't await — don't add latency):
db.apiKey.update({
where: { id: key.id },
data: { lastUsedAt: new Date() },
}).catch(() => {});
return key;
}
export async function revokeApiKey(keyId: string, userId: string): Promise<void> {
await db.apiKey.updateMany({
where: { id: keyId, userId },
data: { revokedAt: new Date() },
});
}
Webhook Delivery with Svix
For event-driven API products, Svix handles webhook delivery (retries, HMAC signing, delivery logs):
npm install svix
import { Svix } from 'svix';
const svix = new Svix(process.env.SVIX_AUTH_TOKEN!);
// Send a webhook when an async operation completes:
export async function sendWebhook(
appId: string, // Your customer's app ID in Svix
eventType: string,
payload: object
) {
await svix.message.create(appId, {
eventType,
payload: {
...payload,
timestamp: new Date().toISOString(),
},
});
}
// Example: after async processing job completes:
await sendWebhook(
customer.svixAppId,
'document.processed',
{ documentId, status: 'complete', pageCount: 42 }
);
Svix provides:
- Automatic retries with exponential backoff
- HMAC signature verification for customers
- Delivery logs and replay
- Customer-facing webhook portal (embed in your dashboard)
Free tier: 10,000 messages/month. Svix is the standard for API product webhook delivery.
Rate Limiting Strategy
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const redis = Redis.fromEnv();
// Different limits per plan:
const limits = {
free: new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(100, '1d') }),
starter: new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(10_000, '1d') }),
pro: new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(1_000_000, '1m') }),
};
export async function checkRateLimit(apiKey: ApiKey, plan: 'free' | 'starter' | 'pro') {
const limiter = limits[plan];
const result = await limiter.limit(apiKey.id);
return {
allowed: result.success,
remaining: result.remaining,
reset: new Date(result.reset),
limit: result.limit,
};
}
OpenAPI Spec Generation
Auto-generate client SDKs and documentation from your API spec:
// Using Hono + zod-openapi:
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
const app = new OpenAPIHono();
const TranscribeRoute = createRoute({
method: 'post',
path: '/transcribe',
request: {
body: {
content: {
'application/json': {
schema: z.object({
audio_url: z.string().url(),
language: z.string().optional().default('en'),
}),
},
},
},
},
responses: {
200: {
content: {
'application/json': {
schema: z.object({
text: z.string(),
words: z.array(z.object({ word: z.string(), start: z.number(), end: z.number() })),
}),
},
},
description: 'Transcription result',
},
},
});
// OpenAPI spec at /openapi.json:
app.doc('/openapi.json', { openapi: '3.0.0', info: { title: 'Transcription API', version: '1.0.0' } });
Generate SDKs: npx @speakeasy-api/speakeasy generate sdk --schema ./openapi.json --lang typescript
Recommended Stack by API Product Type
| API Product Type | Boilerplate | Add |
|---|---|---|
| AI/LLM API | Midday v1 | API keys + Stripe Meters |
| Data processing API | Midday v1 | Trigger.dev jobs (included) |
| Usage-metered API | Makerkit | Stripe Meters (included) |
| Webhook-heavy API | OpenSaaS | Svix |
| Simple REST API | T3 Stack | API keys + Stripe |
| Real-time API | Custom | WebSockets / SSE |
Methodology
Based on publicly available information from each boilerplate's documentation, Stripe API documentation, Svix documentation, and community resources as of March 2026.
Building an API product? StarterPick helps you find the right boilerplate based on your billing model, usage patterns, and technical requirements.