Disclosure: This article contains affiliate links. If you sign up through them, I earn a small commission at no extra cost to you. I only recommend tools I use myself.
Every production app lives and dies by its API choices. Pick the wrong one and you're fighting authentication quirks, terrible documentation, and rate limits that hit you at 2 AM. Pick the right one and your feature is live in an afternoon.
This is a practical rundown of the APIs worth integrating in 2026 — not a popularity contest, but a category-by-category guide with real code so you can evaluate them honestly.
What Makes an API Worth Using in 2026?
Before the list, the criteria I'm judging by:
- SDK quality — does the TypeScript SDK feel like someone actually uses it?
- Developer experience — dashboard, docs, error messages
- Pricing model — is there a free tier? Does it scale without surprises?
- Reliability — status page history, uptime track record
- Community — GitHub issues answered, active Discord/Slack
Payments
1. Stripe — Still the Default
Stripe remains the benchmark for payment APIs. Its TypeScript SDK is excellent, the webhook infrastructure is reliable, and the dashboard gives you everything you need to debug a failed payment at 3 AM.
// Install: npm install stripe
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// Create a checkout session
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [
{
price_data: {
currency: 'usd',
product_data: { name: 'Pro Plan' },
unit_amount: 2900, // $29.00
recurring: { interval: 'month' },
},
quantity: 1,
},
],
mode: 'subscription',
success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard?success=true`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
});Webhook verification — never skip this:
// app/api/webhooks/stripe/route.ts
import { headers } from 'next/headers';
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(request: Request) {
const body = await request.text();
const signature = headers().get('stripe-signature')!;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
} catch (err) {
return new Response('Invalid signature', { status: 400 });
}
switch (event.type) {
case 'checkout.session.completed':
await handleSuccessfulPayment(event.data.object);
break;
case 'customer.subscription.deleted':
await handleCancellation(event.data.object);
break;
}
return new Response('OK');
}Pricing: 2.9% + $0.30 per transaction. No monthly fees.
When to use it: Any SaaS, e-commerce, or marketplace that handles money. The ecosystem around Stripe (Stripe Tax, Billing, Connect) means you can build complex payment flows without stitching together multiple providers.
2. Resend — The Modern Email API
Resend launched in 2023 and quickly became the preferred choice for developers who want to send transactional email without wrestling with legacy infrastructure. The SDK is clean, React Email integration is first-class, and deliverability is solid.
// Install: npm install resend @react-email/components
import { Resend } from 'resend';
import { WelcomeEmail } from '@/emails/welcome';
const resend = new Resend(process.env.RESEND_API_KEY);
// Send with a React Email template
const { data, error } = await resend.emails.send({
from: 'StackNotice <hello@stacknotice.com>',
to: [user.email],
subject: 'Welcome to StackNotice',
react: <WelcomeEmail name={user.name} />,
});
if (error) {
console.error('Email send failed:', error);
throw new Error(error.message);
}The React Email template itself:
// emails/welcome.tsx
import {
Body, Container, Head, Heading, Html,
Preview, Text, Button
} from '@react-email/components';
interface WelcomeEmailProps {
name: string;
}
export function WelcomeEmail({ name }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Preview>Welcome to StackNotice, {name}</Preview>
<Body style={{ fontFamily: 'sans-serif', background: '#f9fafb' }}>
<Container style={{ maxWidth: '580px', margin: '0 auto', padding: '24px' }}>
<Heading>Welcome, {name}</Heading>
<Text>Your account is ready. Here's where to start:</Text>
<Button
href="https://stacknotice.com/dashboard"
style={{ background: '#F97316', color: '#fff', padding: '12px 24px' }}
>
Open Dashboard
</Button>
</Container>
</Body>
</Html>
);
}Pricing: 3,000 emails/month free. $20/month for 50k emails.
When to use it: New projects, teams already using React. The local preview server (npx react-email dev) is a genuine productivity win — you see your email template render in the browser as you write it.
For a deeper integration walkthrough, see the Resend + Next.js complete guide.
AI and Language Models
3. Anthropic Claude API — Best for Complex Tasks
Claude's API produces high-quality output on reasoning-heavy tasks and handles long documents well thanks to its 200k context window. The Messages API is straightforward.
// Install: npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
// Streaming response
const stream = await client.messages.stream({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{
role: 'user',
content: 'Review this pull request diff and identify any potential bugs.',
},
],
system: 'You are a senior engineer doing code review. Be specific and direct.',
});
for await (const chunk of stream) {
if (
chunk.type === 'content_block_delta' &&
chunk.delta.type === 'text_delta'
) {
process.stdout.write(chunk.delta.text);
}
}With tools (function calling):
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
tools: [
{
name: 'get_weather',
description: 'Get current weather for a location',
input_schema: {
type: 'object' as const,
properties: {
location: { type: 'string', description: 'City name' },
},
required: ['location'],
},
},
],
messages: [{ role: 'user', content: "What's the weather in Berlin?" }],
});Pricing: claude-haiku-4-5 at $0.80/1M input tokens is cost-effective for high volume. claude-sonnet-4-6 at $3/1M input hits the sweet spot for most production use. See the Claude API complete guide for a full pricing breakdown.
When to use it: Document analysis, code review automation, customer support workflows, anything where output quality matters more than raw speed.
4. OpenAI API — Largest Ecosystem
OpenAI's API has the largest third-party tooling ecosystem, the widest model selection, and gpt-4o-mini is remarkably capable at its price point.
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// Structured output with JSON mode
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{
role: 'user',
content: 'Extract the name, email, and company from this text: John Smith, john@acme.com, works at Acme Corp',
},
],
response_format: { type: 'json_object' },
});
const data = JSON.parse(completion.choices[0].message.content!);
// { name: "John Smith", email: "john@acme.com", company: "Acme Corp" }For a detailed side-by-side, see OpenAI API vs Claude API.
Communication
5. Twilio — Voice and SMS
Twilio is the default for phone verification, SMS notifications, and voice calls. The pricing is per-message/per-minute which makes cost predictable at low volume, though it adds up at scale.
// Install: npm install twilio
import twilio from 'twilio';
const client = twilio(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_AUTH_TOKEN
);
// Send SMS
const message = await client.messages.create({
body: 'Your verification code is 847291. Valid for 10 minutes.',
from: process.env.TWILIO_PHONE_NUMBER,
to: '+14155552671',
});
// Phone verification flow
const verification = await client.verify.v2
.services(process.env.TWILIO_VERIFY_SERVICE_SID!)
.verifications.create({
to: phoneNumber,
channel: 'sms',
});Verifying the code:
const check = await client.verify.v2
.services(process.env.TWILIO_VERIFY_SERVICE_SID!)
.verificationChecks.create({ to: phoneNumber, code: userInputCode });
if (check.status !== 'approved') {
throw new Error('Invalid or expired verification code');
}Pricing: ~$0.0079/SMS in the US. Phone numbers from $1/month.
When to use it: Phone verification, SMS alerts, two-factor authentication. For pure notifications (no phone numbers needed), Resend or a push service is cheaper.
File Storage and Media
6. Cloudinary — Image and Video Transformation
Cloudinary's real value isn't storage — it's the URL-based transformation API. You upload once and serve optimized versions on demand without writing any image processing code.
// Install: npm install cloudinary
import { v2 as cloudinary } from 'cloudinary';
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
// Upload
const result = await cloudinary.uploader.upload(filePath, {
folder: 'avatars',
transformation: [
{ width: 400, height: 400, crop: 'fill', gravity: 'face' },
{ quality: 'auto', fetch_format: 'auto' },
],
});
console.log(result.secure_url);
// https://res.cloudinary.com/your-cloud/image/upload/v1234/avatars/user123.webpURL-based transforms (no upload needed):
function getOptimizedImageUrl(publicId: string, width: number) {
return cloudinary.url(publicId, {
width,
crop: 'scale',
quality: 'auto',
fetch_format: 'auto',
secure: true,
});
}
// Returns a URL that serves the right format (WebP, AVIF) for the browserPricing: 25 credits/month free (roughly 25k transformations). Paid plans from $89/month.
When to use it: Apps with user-generated images, profile avatars, product photos. The face-detection crop alone saves hours of manual work.
7. UploadThing — Simple File Uploads for Next.js
If you just need file uploads and don't need video transcoding or image transformations, UploadThing is dramatically simpler to set up. It's built specifically for Next.js.
// app/api/uploadthing/core.ts
import { createUploadthing, type FileRouter } from 'uploadthing/next';
import { auth } from '@clerk/nextjs';
const f = createUploadthing();
export const ourFileRouter = {
imageUploader: f({ image: { maxFileSize: '4MB', maxFileCount: 4 } })
.middleware(async () => {
const { userId } = auth();
if (!userId) throw new Error('Unauthorized');
return { userId };
})
.onUploadComplete(async ({ metadata, file }) => {
await db.insert(uploads).values({
userId: metadata.userId,
url: file.url,
name: file.name,
});
return { url: file.url };
}),
} satisfies FileRouter;Client component:
'use client';
import { UploadButton } from '@uploadthing/react';
export function AvatarUpload() {
return (
<UploadButton
endpoint="imageUploader"
onClientUploadComplete={(files) => {
console.log('Uploaded:', files[0].url);
}}
/>
);
}See the UploadThing + Next.js guide for the full setup including drag-and-drop.
Maps and Location
8. Mapbox — Customizable Maps
Mapbox gives you more design control than Google Maps and has a more generous free tier (50,000 map loads/month). The GL JS library renders maps in WebGL, which means smooth performance at any zoom level.
// Install: npm install mapbox-gl @types/mapbox-gl
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN!;
// In your component
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v11',
center: [-74.006, 40.7128], // New York
zoom: 12,
});
// Add a marker
new mapboxgl.Marker({ color: '#F97316' })
.setLngLat([-74.006, 40.7128])
.setPopup(new mapboxgl.Popup().setHTML('<h3>Office</h3><p>123 Main St</p>'))
.addTo(map);Pricing: 50k map loads/month free. $5 per 1,000 after that.
When to use it: Location-aware apps, property listings, delivery tracking, any app where the map style needs to match your brand.
Authentication
9. Clerk — Auth That Just Works
Clerk handles the entire authentication surface — signup, login, MFA, social providers, organization management — with pre-built UI components. For most SaaS projects, it removes weeks of auth work.
// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/api/(.*)']);
export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect();
});// app/layout.tsx
import { ClerkProvider } from '@clerk/nextjs';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
);
}Getting the current user in a server component:
import { auth, currentUser } from '@clerk/nextjs/server';
export default async function Dashboard() {
const { userId } = auth();
const user = await currentUser();
return <div>Welcome, {user?.firstName}</div>;
}Pricing: Free up to 10,000 MAU. $25/month for more. (At 50k MAU it gets expensive — see Clerk vs Better Auth for alternatives.)
When to use it: Early-stage SaaS where you want auth done fast. Reconsider at scale due to pricing.
Real-Time
10. Pusher Channels — WebSocket Made Simple
Pusher manages WebSocket connections at scale so you don't have to run your own socket infrastructure. The hosted model handles reconnections, presence, and private channels.
// Server-side: trigger an event
import Pusher from 'pusher';
const pusher = new Pusher({
appId: process.env.PUSHER_APP_ID!,
key: process.env.PUSHER_KEY!,
secret: process.env.PUSHER_SECRET!,
cluster: process.env.PUSHER_CLUSTER!,
useTLS: true,
});
await pusher.trigger('notifications', 'new-message', {
userId: 'user_123',
message: 'Your report is ready',
timestamp: Date.now(),
});// Client-side: subscribe
import PusherJS from 'pusher-js';
import { useEffect } from 'react';
export function useRealtimeNotifications(userId: string) {
useEffect(() => {
const pusher = new PusherJS(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
});
const channel = pusher.subscribe(`private-user-${userId}`);
channel.bind('notification', (data: { message: string }) => {
toast(data.message);
});
return () => pusher.unsubscribe(`private-user-${userId}`);
}, [userId]);
}Pricing: 200k messages/day free. $49/month for 5M messages/day.
When to use it: Live dashboards, notifications, collaborative features where you need fast setup. For Next.js apps, SSE is a solid alternative at lower volume without the extra dependency.
Analytics and Error Tracking
11. PostHog — Product Analytics + Feature Flags
PostHog does product analytics, session recording, feature flags, and A/B testing in a single SDK. It's open-source and can be self-hosted, which matters if you're in a regulated industry.
// Install: npm install posthog-js posthog-node
// Server-side events
import { PostHog } from 'posthog-node';
const posthog = new PostHog(process.env.POSTHOG_API_KEY!, {
host: 'https://us.i.posthog.com',
});
// Track a conversion event
posthog.capture({
distinctId: userId,
event: 'subscription_started',
properties: {
plan: 'pro',
billing_cycle: 'monthly',
mrr: 29,
},
});
// Feature flag check
const isEnabled = await posthog.isFeatureEnabled('new-checkout', userId);// Client-side provider
'use client';
import posthog from 'posthog-js';
import { PostHogProvider } from 'posthog-js/react';
import { useEffect } from 'react';
export function Analytics({ children }: { children: React.ReactNode }) {
useEffect(() => {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
api_host: '/ingest',
capture_pageview: false, // handle manually with App Router
});
}, []);
return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
}Pricing: 1M events/month free (no card required). Generous for early-stage products.
12. Sentry — Error Tracking
A production app without Sentry is flying blind. It catches uncaught exceptions, slow database queries, and frontend crashes with full stack traces.
// Install: npm install @sentry/nextjs
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.1, // 10% of transactions
environment: process.env.NODE_ENV,
beforeSend(event) {
// Strip sensitive data before sending
if (event.user) delete event.user.email;
return event;
},
});Manual error capture with context:
try {
await processPayment(orderId);
} catch (error) {
Sentry.captureException(error, {
tags: { component: 'payment', orderId },
user: { id: userId },
});
throw error; // still throw, Sentry just records it
}Pricing: 5k errors/month free. $26/month for teams.
Background Jobs
13. Trigger.dev — Background Jobs in TypeScript
Trigger.dev runs long-running tasks outside your serverless function timeout. Define your jobs in TypeScript, trigger them from anywhere, and get full observability into every run.
// Install: npm install @trigger.dev/sdk
import { task } from '@trigger.dev/sdk/v3';
import { Resend } from 'resend';
export const sendWelcomeSequence = task({
id: 'send-welcome-sequence',
run: async (payload: { userId: string; email: string }) => {
const resend = new Resend(process.env.RESEND_API_KEY);
// Step 1: immediate welcome
await resend.emails.send({
from: 'hello@stacknotice.com',
to: payload.email,
subject: 'Welcome',
html: '<p>Welcome aboard!</p>',
});
// Step 2: wait 2 days, send onboarding tips
await new Promise((resolve) => setTimeout(resolve, 2 * 24 * 60 * 60 * 1000));
await resend.emails.send({
from: 'hello@stacknotice.com',
to: payload.email,
subject: 'Getting started tips',
html: '<p>Here are 5 things to try first...</p>',
});
},
});
// Trigger from an API route
import { tasks } from '@trigger.dev/sdk/v3';
await tasks.trigger('send-welcome-sequence', {
userId: user.id,
email: user.email,
});Pricing: 50k task runs/month free. $20/month for 500k runs.
When to use it: Email sequences, PDF generation, AI processing pipelines, anything that takes longer than a Vercel serverless function timeout (10s on hobby, 60s on pro).
Search
14. Algolia — Instant Search
Algolia delivers search results in under 50ms globally. The InstantSearch UI components work with React and handle faceting, pagination, and highlighting out of the box.
// Install: npm install algoliasearch instantsearch.js react-instantsearch
import algoliasearch from 'algoliasearch';
const client = algoliasearch(
process.env.ALGOLIA_APP_ID!,
process.env.ALGOLIA_ADMIN_API_KEY!
);
const index = client.initIndex('articles');
// Index a record
await index.saveObject({
objectID: article.id,
title: article.title,
content: article.content,
tags: article.tags,
publishedAt: article.publishedAt,
});
// Search (typically called server-side for SSR)
const results = await index.search('react hooks', {
hitsPerPage: 10,
filters: 'category:react',
});// React InstantSearch
import { InstantSearch, SearchBox, Hits } from 'react-instantsearch';
import algoliasearch from 'algoliasearch/lite';
const searchClient = algoliasearch(
process.env.NEXT_PUBLIC_ALGOLIA_APP_ID!,
process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY!
);
export function Search() {
return (
<InstantSearch indexName="articles" searchClient={searchClient}>
<SearchBox placeholder="Search articles..." />
<Hits hitComponent={ArticleHit} />
</InstantSearch>
);
}Pricing: 10k records + 10k search operations/month free. Paid plans from $50/month.
When to use it: Documentation sites, e-commerce product search, any search where you need sub-100ms response times globally.
Database
15. Neon — Serverless Postgres
Neon runs Postgres on serverless infrastructure with scale-to-zero and branching. You get a full Postgres database that costs nothing when idle and scales automatically under load.
// Install: npm install @neondatabase/serverless drizzle-orm
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);
// Works exactly like regular Drizzle
const users = await db
.select()
.from(usersTable)
.where(eq(usersTable.id, userId));Database branching for PRs:
# Create a branch for your feature
neon branches create --name feature/add-payments
# Run migrations on the branch
DATABASE_URL=postgres://branch-url npx drizzle-kit migrate
# Branch is deleted when the PR merges
neon branches delete feature/add-paymentsPricing: Free tier with 0.5GB storage and 190 compute hours/month. Pro plan at $19/month.
See the Neon + Next.js complete guide for full setup including connection pooling.
Decision Guide
| Job | First Choice | Alternative | Avoid |
|---|---|---|---|
| Payments | Stripe | Lemon Squeezy (SaaS) | PayPal API |
| Resend | Postmark | SendGrid (legacy DX) | |
| AI / LLM | Claude API | OpenAI | Cohere (smaller ecosystem) |
| SMS / Phone | Twilio | Vonage | Rolling your own |
| Image transform | Cloudinary | imgix | Sharp in serverless |
| File uploads | UploadThing | S3 + presigned | FormData to your DB |
| Maps | Mapbox | Google Maps | Leaflet + OSM (no support) |
| Auth | Clerk | Better Auth | Rolling your own |
| Real-time | Pusher | SSE (self) | Long polling |
| Analytics | PostHog | Mixpanel | GA4 for product analytics |
| Error tracking | Sentry | Highlight.io | Console.log |
| Background jobs | Trigger.dev | Inngest | cron + DB table |
| Search | Algolia | Typesense (self-host) | LIKE queries |
| Database | Neon | PlanetScale | SQLite on serverless |
How to Evaluate Any New API
When a new API shows up in your Slack and someone wants to add it, run through this list before committing:
-
SDK type coverage — open the npm page and check if there's a TypeScript SDK. If there's only a REST API with no official SDK, the integration work doubles.
-
Error messages — create a free account and intentionally break something. Good APIs return
{ error: { code: "invalid_api_key", message: "The API key provided is not valid" } }. Bad ones return{ error: "Authentication failed" }. -
Pricing floor — calculate what you'll pay at 1k users, 10k users, and 100k users. Some APIs have great free tiers but pricing cliffs that make them unworkable at scale.
-
Status page — check their status page history. Three incidents in the last 30 days is a red flag regardless of how good the DX is.
-
Migration path — what does it look like to leave? If their entire product is their proprietary format with no export, that's lock-in worth knowing about upfront.
The APIs on this list have earned their place through real production use, not marketing. Some have better pricing than others, some have better developer experience — but all of them are genuinely useful to build with. Start with the ones that match your current needs, and add the others when you actually need them rather than preemptively.
For more on building production apps with these tools, the fullstack project setup guide covers how to wire them together from day one.