How to Build a REST API Backend With Claude Code: Step-by-Step Guide (2026)
To build a REST API backend with Claude Code, you work through 7 steps: plan your endpoints and schema, scaffold the project and data layer, build CRUD one resource at a time, add auth and validation, test, harden for production, then deploy. Claude Code handles the boilerplate (scaffolding, models, migrations, tests) while you own the auth and security review. A basic CRUD API takes roughly 30-60 minutes. This guide builds a real "tasks" API on Express + Prisma + PostgreSQL, with runnable code and actual JSON responses.
by Jasmine, a dev who ships backends with Claude Code daily.
Why use Claude Code to build a REST API backend?
Claude Code is an agentic CLI: it reads your whole repo, generates several files at once, then runs commands and tests to check its own work (per Anthropic's official docs, updated 2026). That trait is exactly why it fits backend work better than a paste-the-code chatbot. A REST API is, at heart, a pile of repetitive boilerplate - models, migrations, CRUD controllers, validation, tests, docs. It is time-consuming, low-creativity work, and that is where AI speeds you up the most.
The biggest win is scaffolding speed. Instead of hand-typing six near-identical endpoints, you describe the resource once and Claude Code generates both the data layer and the REST layer, then runs it. It is also good at the "tedious" parts, like writing a Zod or Pydantic schema that matches your model, or standing up a test suite for each route.
But here is the part you have to keep for yourself: you are still the reviewer. Claude Code does not understand your security context - it tends to ship loose defaults (missing authz on a route, secrets in code, validation for show). For anything touching money or permissions, what the AI produces is only a strong first draft. If you are new to the tool, read what Claude Code is first to see how it works before you hand it backend work.
What to prepare before you start
A checklist to run before you open Claude Code - get these in place so the whole session flows:
- Claude Code installed and working in your terminal - see the Claude Code installation guide if you have not set it up.
- Runtime: Node 20+ (for Express) or Python 3.11+ (for FastAPI).
- Database: PostgreSQL (production-grade) or SQLite (fast dev, no server needed).
- A Git repo already run through
git init- so you can review each diff and revert when needed. - A
CLAUDE.mdfile that spells out project conventions - this is the single biggest difference between clean output and a mess.
Put CLAUDE.md at the repo root and Claude Code reads it automatically every session. For a backend, state your layer conventions, validation, and error shape up front so you are not repeating yourself:
# CLAUDE.md - backend conventions
## Architecture
- Three layers: routes -> controllers -> services. No DB queries in controllers.
- ORM: Prisma. All queries go through a service; no raw SQL unless required.
## Validation & errors
- Validate input with Zod at the top of every handler.
- Errors return JSON: { "error": { "code": string, "message": string } }
- Status codes: 200/201 success, 400 validation, 401 unauthenticated,
403 forbidden, 404 not found, 500 server error.
## Security (REQUIRED, do not skip)
- NEVER hardcode secrets. Read them from process.env.
- Every write/update/delete route must pass through auth middleware.
- Never return sensitive fields (passwordHash) in a response.
## Tests
- Every endpoint has at least 1 happy-path test + 1 error test (Jest + Supertest).
With this one file, the quality of what Claude Code generates jumps a level - because it now has a "contract" to follow instead of guessing your style.
Choosing a stack - Node/Express or Python/FastAPI?
There is no single "correct" stack, but some fit the way Claude Code works better than others. A quick comparison of four popular choices:
| Stack | Scaffold speed | Type safety | Ecosystem | Fit with Claude Code |
|---|---|---|---|---|
| Express + Prisma | Very fast | Decent (via TS + Prisma) | Huge (JS) | High - lots of familiar patterns |
| FastAPI + SQLAlchemy | Fast | High (Pydantic type hints) | Large (Python) | Very high - type hints cut hallucinations |
| NestJS | Medium | Very high | Large | Medium - heavy boilerplate, decorators |
| Django REST | Medium | Medium | Huge (Python) | Decent - strict conventions, less flexible |
For this whole guide I am going with Express + Prisma + PostgreSQL: JS-first, widely used, and Prisma gives enough type safety without the weight of NestJS. If your team is on Python, FastAPI + SQLAlchemy is excellent too - Pydantic's type hints actually help Claude Code produce fewer type errors. The key point: pick one stack and stick with it for the whole build. Do not let Claude Code "choose for itself" mid-project - that is the recipe for a hybrid mess nobody wants to maintain.
Step 1 - Plan endpoints and schema with Claude Code
Do not tell Claude Code "build me an API" and let it start coding. Begin with planning: have it brainstorm the resources, endpoints, and DB schema first, so you can approve the design before a single line of code exists. A copy-paste prompt:
I want to build a REST API for managing "tasks" with Express + Prisma + PostgreSQL.
Before writing code, propose:
1. The endpoint list (method + path + description) for tasks CRUD.
2. The Task table schema (fields, types, constraints).
3. A sample response shape for each endpoint.
Present it as a table. DO NOT code yet - I want to review first.
Claude Code returns an endpoint table like this for you to sign off on:
| Method | Path | Description |
|---|---|---|
| GET | /tasks | List tasks (with pagination) |
| GET | /tasks/:id | Get a single task |
| POST | /tasks | Create a task |
| PATCH | /tasks/:id | Partial update |
| DELETE | /tasks/:id | Delete a task |
Review carefully here: are the fields complete, do you need a status enum, is pagination cursor- or offset-based? Fixing the design in words is far cheaper than fixing generated code. This is also where the plan-before-you-code mindset with Claude Code pays off.
Step 2 - Scaffold the project and data layer
With the design locked, now you let Claude Code scaffold. The prompt:
Scaffold an Express + TypeScript project per the plan we just approved:
- Install express, prisma, @prisma/client, zod, dotenv.
- Create the Prisma schema for the Task model as designed.
- Generate the first migration and a seed file with 3 sample tasks.
- Folder structure: src/routes, src/controllers, src/services, src/lib.
After creating it, STOP so I can read the migration before it runs.
The resulting Prisma schema should look like this:
// prisma/schema.prisma
model Task {
id String @id @default(uuid())
title String
detail String?
status Status @default(TODO)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum Status {
TODO
DOING
DONE
}
Read the migration before you run it - this is not boilerplate advice. Claude Code sometimes adds an extra column, sets a wrong default, or skips a needed index. Run npx prisma migrate dev --name init only once you understand the diff. If you want to go deeper on this part, see using Claude Code with your database.
Step 3 - Build CRUD endpoints one resource at a time
The golden rule: one endpoint at a time, not "build them all at once". When you ask Claude Code for five routes in one shot, it tends to drift and you struggle to review. Do one, review it, commit, then move to the next. Start with POST and GET:
// src/controllers/task.controller.ts
import { Request, Response } from "express";
import { z } from "zod";
import * as taskService from "../services/task.service";
const createSchema = z.object({
title: z.string().min(1).max(200),
detail: z.string().max(2000).optional(),
status: z.enum(["TODO", "DOING", "DONE"]).optional(),
});
export async function createTask(req: Request, res: Response) {
const parsed = createSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({
error: { code: "VALIDATION_ERROR", message: parsed.error.message },
});
}
const task = await taskService.create(parsed.data);
return res.status(201).json(task);
}
export async function listTasks(req: Request, res: Response) {
const tasks = await taskService.findAll();
return res.status(200).json(tasks);
}
Two things to check on review: does the response shape match your CLAUDE.md (is the error object in the right form), and is the status code semantically correct (201 for creation, not 200). This is where Claude Code gets sloppy - it will often return 200 for everything unless you spell it out.
Claude Code uses skills to standardize these patterns, so if you have your own backend skill, the output will be far more consistent than a bare prompt.
Step 4 - Auth and validation (JWT or API key)
Most tutorials stop at "add JWT if required." Not good enough. Here is real JWT middleware that protects the write/update/delete routes:
// src/lib/auth.ts
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
export function requireAuth(req: Request, res: Response, next: NextFunction) {
const header = req.headers.authorization;
if (!header?.startsWith("Bearer ")) {
return res.status(401).json({
error: { code: "UNAUTHORIZED", message: "Missing token" },
});
}
try {
const payload = jwt.verify(header.slice(7), process.env.JWT_SECRET!);
(req as any).user = payload;
next();
} catch {
return res.status(401).json({
error: { code: "INVALID_TOKEN", message: "Invalid token" },
});
}
}
Attach it to write routes: router.post("/tasks", requireAuth, createTask). For a simple internal API, matching a constant API key is enough too - but always compare with a timing-safe function, never a bare ===.
Manual review required: Claude Code tends to ship weak defaults - forgetting to attach
requireAuthto the right route, lettingJWT_SECRETfall back to a hardcoded string, or skipping the ownership check (user A can edit user B's task). After the AI generates the middleware, go back through by hand: does every sensitive route have auth, is the secret read fromenv, and is authz (not just authn) actually correct?
Step 5 - Test the API (pairing TDD with AI)
Claude Code does not just write tests, it runs the tests and curl itself to verify - this is the real agentic advantage. Prompt: "Write Jest + Supertest tests for POST /tasks and GET /tasks, covering happy-path and a validation-error case, then run them." A sample test:
// tests/task.test.ts
import request from "supertest";
import app from "../src/app";
describe("POST /tasks", () => {
it("creates a valid task and returns 201", async () => {
const res = await request(app)
.post("/tasks")
.set("Authorization", `Bearer ${process.env.TEST_TOKEN}`)
.send({ title: "Write post F1" });
expect(res.status).toBe(201);
expect(res.body.title).toBe("Write post F1");
});
it("returns 400 when title is missing", async () => {
const res = await request(app)
.post("/tasks")
.set("Authorization", `Bearer ${process.env.TEST_TOKEN}`)
.send({});
expect(res.status).toBe(400);
});
});
Verify by hand with curl to see the real JSON response:
$ curl -s -X POST http://localhost:3000/tasks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Write post F1","status":"DOING"}'
{
"id": "a3f1c9e2-...-8b71",
"title": "Write post F1",
"detail": null,
"status": "DOING",
"createdAt": "2026-08-09T04:12:30.882Z",
"updatedAt": "2026-08-09T04:12:30.882Z"
}
Having Claude Code write the tests before it implements is the effective way to apply TDD with AI: the tests act as the "contract" and the AI codes until they go green.
Step 6 - Production security and error handling
This is the part competitors leave nearly blank. Before you expose the API to the internet, have Claude Code add the following layers - but review the checklist yourself:
- Rate limiting:
express-rate-limitto block brute-force and abuse (say, 100 req/min/IP). - CORS: whitelist specific origins; do not leave
origin: "*"on an authenticated API. - Env/secrets: every key via
.env, add.envto.gitignore, ship a.env.exampletemplate. - Input validation: already handled by Zod in each handler - never trust client data.
- Central error handler: a final middleware that catches all errors and does not leak stack traces in production responses.
- Helmet: set the basic HTTP security headers.
A short OWASP checklist to run through: any injection (Prisma blocks SQLi via parameterized queries), any broken access control (check authz on each route), any sensitive data exposure (do not return extra fields). If you want Claude Code to scan for holes itself, see how to run a security audit with Claude Code.
Step 7 - Deploy the API to a real URL
I use Railway for this demo because it provisions Postgres out of the box and deploys from Git in a few minutes. The steps:
- Push the repo to GitHub.
- On Railway, create a project from the repo and add a PostgreSQL service - it auto-generates
DATABASE_URL. - Set the production env vars:
JWT_SECRET,DATABASE_URL,NODE_ENV=production. - Set the build command
npx prisma migrate deploy && npm run buildand the start commandnpm start.
If you want it more portable (runnable on Render, Fly.io, or a VPS too), add a minimal Dockerfile:
# Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx prisma generate && npm run build
EXPOSE 3000
CMD ["npm", "start"]
After deploying, hit the endpoint over the live URL to confirm the migration ran and the env is correct. Platform-by-platform detail is in the guide on deploying apps with Claude Code.
Going faster: AgentKit ships the ak-backend-development skill
One line to avoid confusion: AgentKit here is a kit bundle for Claude Code (agentkit.best, the ak CLI) - not OpenAI's AgentKit (Agent Builder/ChatKit, launched 2025-10-06). Same name, completely different things.
All 7 steps above ask you to declare conventions in CLAUDE.md and re-state patterns each session. AgentKit for Claude Code (20% off via link) packages the ak-backend-development skill that, per its listing, supports Node/Python/Go (NestJS, FastAPI, Django), OAuth/JWT auth, an OWASP security checklist, and Docker/K8s. In other words, Claude Code runs these same 7 steps against ready-made standard conventions, so you are not rebuilding the "contract" from scratch on every project.
Honest take: the kit is not mandatory - you can do all of this by hand, and this article just proved it. The kit only saves setup effort if you build backends often. The Engineer Kit is $99 (the site does not mention a recurring fee), with a "money-back guarantee" and "lifetime updates." See what is inside AgentKit's Engineer Kit to weigh it before buying.
Real limits and when you must review by hand
This is the section no competitor has, and it is the most important one. After many backend projects with Claude Code, these are the failure modes I keep having to catch:
- Wrong imports/ORM calls: calling a Prisma method that does not exist, or importing the wrong package version - the code looks right but fails at runtime.
- Missing authz on a route: it has authn (who you are) but skips authz (whether you may) - a user edits someone else's data.
- Loose validation: validates the title but forgets a length limit, forgets to sanitize, lets odd data types through.
- N+1 queries: a loop hitting the DB per item instead of one query - fine in dev, falls over in production.
- Hardcoded secrets: a
JWT_SECRETor connection string dropped straight into code as a fallback. - "Looks like it runs" but wrong business logic: it compiles, the happy-path test is green, but the calculation or state logic is wrong - only someone who knows the domain will catch it.
My rule: Claude Code for boilerplate, humans review for auth, security, and money logic. The AI generates 80% of the volume many times faster; the remaining 20% - exactly the high-risk part - is where you cannot go hands-off. That is not a weakness of the tool, it is how you use it correctly.
Frequently asked questions (FAQ)
Is Claude Code production-ready for backends?
Not fully automated. Claude Code generates real, working, well-structured code, but the auth, permissions, security, and business logic need a careful human review before production. Treat the output as a high-quality first draft, not a final version.
Do I need to know how to code, or can a beginner do it?
You need to be able to read code and understand HTTP/REST and databases at a basic level to review the output. A beginner can still get a working API, but will struggle to spot the security or logic bugs Claude Code introduces - so learn alongside it, do not hand it off blindly.
Can it build GraphQL or gRPC?
Yes. This guide demos REST because it is the most common, but Claude Code can build GraphQL (Apollo) and gRPC too. The principles are identical: plan the schema first, build in pieces, and review the auth/security yourself.
Which stack fits Claude Code best?
Express + Prisma (JS) and FastAPI + SQLAlchemy (Python) are the two best fits - lots of familiar patterns and enough type safety to reduce hallucinations. FastAPI has an edge because its type hints cut down on type errors.
Is the code Claude Code generates secure?
Not by default. Claude Code tends to ship loose defaults: missing authz, secrets in code, thin validation. You have to run the security checklist yourself (rate limiting, CORS, env, OWASP) and review every sensitive route before deploying.
How long does a basic CRUD API take?
About 30-60 minutes for a complete CRUD REST API with basic auth and tests, including review time. Scaffolding and boilerplate are fast; the real time goes into reviewing auth, security, and tuning the business logic.
Conclusion and next steps
To recap the 7 steps: plan endpoints and schema -> scaffold the project and data layer -> build CRUD one resource at a time -> add auth/validation -> test -> harden for production -> deploy. Claude Code handles the boilerplate; you own the auth and logic review - that is the right division of labor. Good next reads: writing tests and TDD with AI to make your API sturdier, and deploying apps with Claude Code to get it onto a real URL.
Want Claude Code to build backends faster? If you stand up APIs often, the ready-made ak-backend-development kit lets Claude Code follow standard conventions without you re-declaring them every time. It is not mandatory - doing it by hand works fine.