Stop using a single generic AI assistant for every step of API development. Instead, set up 5 specialized agents to build a robust API: Backend Architect (system design), Database Optimizer (schema review), Frontend Developer (client app), Code Reviewer (security audit), and Reality Checker (final validation).
If you need to build an API quickly, you might be tempted to use one AI for everything—database design, endpoint writing, frontend implementation, code review, and testing. This usually leads to overlooked indexes, security gaps, poor error handling, and shallow testing.
Specialized agents solve this. Each agent focuses on a domain, follows a checklist, and produces concrete deliverables. The Backend Architect thinks about scalability. The Database Optimizer finds missing indexes. The Code Reviewer hunts vulnerabilities. The Reality Checker demands proof.
This guide shows you how to set up 5 agents from The Agency collection and run a full API build workflow. You’ll integrate with Apidog for API testing and documentation, and ensure endpoints are validated against OpenAPI specs before deployment.
The 5 Agents You’ll Use
| Agent | Division | Responsibility |
|---|---|---|
| Backend Architect | Engineering | API design, database schema, authentication |
| Database Optimizer | Engineering | Index recommendations, query optimization |
| Frontend Developer | Engineering | React components, API client, state management |
| Code Reviewer | Engineering | Security audit, type safety, error handling |
| Reality Checker | Testing | Evidence-based validation, screenshot proof |
Install the agents:
# Clone The Agency repo
git clone https://github.com/msitarzewski/agency-agents.git
cd agency-agents
# Copy agents to Claude Code
cp engineering/engineering-backend-architect.md ~/.claude/agents/
cp engineering/engineering-database-optimizer.md ~/.claude/agents/
cp engineering/engineering-frontend-developer.md ~/.claude/agents/
cp engineering/engineering-code-reviewer.md ~/.claude/agents/
cp testing/testing-reality-checker.md ~/.claude/agents/
Step 1: Backend Architect Designs the System
Start a new Claude Code session and activate Backend Architect mode. Prompt:
Activate Backend Architect mode.
Design a REST API for an e-commerce platform with:
- User authentication (JWT with refresh tokens)
- Product catalog with categories and filtering
- Shopping cart management
- Order processing with status tracking
- Payment webhook integration
Output:
1. OpenAPI 3.0 specification
2. PostgreSQL database schema with relationships
3. Project folder structure (Express.js + TypeScript)
4. Authentication flow diagram
Expected deliverables:
OpenAPI Spec (partial):
openapi: 3.0.0
info:
title: E-commerce API
version: 1.0.0
paths:
/auth/login:
post:
summary: User login
requestBody:
content:
application/json:
schema:
type: object
properties:
email: { type: string, format: email }
password: { type: string, minLength: 8 }
responses:
'200':
description: JWT tokens
content:
application/json:
schema:
type: object
properties:
accessToken: { type: string }
refreshToken: { type: string }
Database Schema:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
category_id UUID REFERENCES categories(id),
inventory_count INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
total_amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
Folder Structure:
src/
├── controllers/
│ ├── auth.controller.ts
│ ├── products.controller.ts
│ └── orders.controller.ts
├── middleware/
│ ├── auth.middleware.ts
│ └── validation.middleware.ts
├── routes/
│ ├── auth.routes.ts
│ ├── products.routes.ts
│ └── orders.routes.ts
├── services/
│ ├── auth.service.ts
│ ├── products.service.ts
│ └── orders.service.ts
├── models/
│ ├── User.ts
│ ├── Product.ts
│ └── Order.ts
└── index.ts
Save this output for the next agent.
Step 2: Database Optimizer Reviews Schema
Open a new session and activate Database Optimizer mode. Prompt:
Activate Database Optimizer mode.
Review this PostgreSQL schema for an e-commerce API:
[Paste the schema from Step 1]
Check for:
1. Missing indexes on foreign keys and frequently queried columns
2. Query performance on product search (name, category, price range)
3. Proper constraints for data integrity
4. Missing tables for common e-commerce features (reviews, wishlists)
5. Soft delete patterns for audit trails
Output specific ALTER TABLE statements and new table definitions.
Expected deliverables:
Index Recommendations:
-- Add indexes on foreign keys
CREATE INDEX idx_products_category_id ON products(category_id);
CREATE INDEX idx_orders_user_id ON orders(user_id);
-- Add index for product search
CREATE INDEX idx_products_name_search ON products USING gin(to_tsvector('english', name));
CREATE INDEX idx_products_price ON products(price) WHERE inventory_count > 0;
-- Add composite index for category filtering
CREATE INDEX idx_products_category_price ON products(category_id, price);
Missing Tables:
CREATE TABLE reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
product_id UUID REFERENCES products(id),
user_id UUID REFERENCES users(id),
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(product_id, user_id)
);
CREATE TABLE cart_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
product_id UUID REFERENCES products(id),
quantity INTEGER DEFAULT 1 CHECK (quantity > 0),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id, product_id)
);
Constraints to Add:
-- Email format validation
ALTER TABLE users ADD CONSTRAINT chk_email_format
CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
-- Soft delete column
ALTER TABLE products ADD COLUMN deleted_at TIMESTAMP WITH TIME ZONE NULL;
CREATE INDEX idx_products_deleted_at ON products(deleted_at) WHERE deleted_at IS NULL;
Integrate these changes into your schema.
Step 3: Frontend Developer Builds the Client
Start a new session and activate Frontend Developer mode. Prompt:
Activate Frontend Developer mode.
Build a React dashboard for this e-commerce API:
[Paste OpenAPI spec from Step 1]
Requirements:
- TypeScript with strict mode
- React Query for server state management
- Product list with filters (category, price range, search)
- Shopping cart with real-time updates
- Order history with status tracking
- Proper error handling and loading states
- Responsive design (mobile, tablet, desktop)
Output:
1. Project setup (Vite + React + TypeScript)
2. API client with React Query hooks
3. Core components (ProductList, ProductCard, Cart, OrderHistory)
4. Error boundary and loading skeletons
API Client Example:
// src/lib/api-client.ts
import { QueryClient, useQuery, useMutation } from '@tanstack/react-query';
const API_BASE = 'http://localhost:3000/api';
async function fetcher<T>(endpoint: string, options?: RequestInit): Promise<T> {
const response = await fetch(`${API_BASE}${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Request failed');
}
return response.json();
}
export function useProducts(filters?: ProductFilters) {
const params = new URLSearchParams(filters as Record<string, string>);
return useQuery({
queryKey: ['products', filters],
queryFn: () => fetcher<Product[]>(`/products?${params}`),
});
}
export function useAddToCart() {
return useMutation({
mutationFn: (item: CartItem) =>
fetcher<CartItem>('/cart', {
method: 'POST',
body: JSON.stringify(item),
}),
});
}
Product List Component Example:
// src/components/ProductList.tsx
import { useProducts } from '@/lib/api-client';
import { ProductCard } from './ProductCard';
import { FilterSidebar } from './FilterSidebar';
import { Skeleton } from './ui/skeleton';
export function ProductList() {
const [filters, setFilters] = useState<ProductFilters>({});
const { data: products, isLoading, error } = useProducts(filters);
if (error) {
return <Alert variant="destructive">{error.message}</Alert>;
}
return (
<div className="flex gap-4">
<FilterSidebar filters={filters} onFilterChange={setFilters} />
<div className="flex-1 grid grid-cols-1 md:grid-cols-3 gap-4">
{isLoading ? (
Array.from({ length: 6 }).map((_, i) => (
<Skeleton key={i} className="h-64" />
))
) : products?.length === 0 ? (
<EmptyState message="No products found" />
) : (
products?.map(product => (
<ProductCard key={product.id} product={product} />
))
)}
</div>
</div>
);
}
Error Boundary Example:
// src/components/ErrorBoundary.tsx
export class ErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ hasError: boolean; error: Error | null }
> {
constructor(props: { children: React.ReactNode }) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
render() {
if (this.state.hasError) {
return (
<div className="p-4 bg-red-50 border border-red-200 rounded">
<h2 className="text-lg font-semibold text-red-800">Something went wrong</h2>
<p className="text-red-600">{this.state.error?.message}</p>
<Button onClick={() => window.location.reload()} className="mt-2">
Reload
</Button>
</div>
);
}
return this.props.children;
}
}
Step 4: Code Reviewer Checks Everything
Open a new session and activate Code Reviewer mode. Prompt:
Activate Code Reviewer mode.
Review this codebase for:
1. Security vulnerabilities:
- SQL injection risks
- XSS vulnerabilities
- CSRF protection
- Authentication bypass possibilities
2. TypeScript strict mode compliance:
- No implicit any
- Proper type definitions
- Null/undefined handling
3. Error handling gaps:
- Uncaught promise rejections
- Missing try/catch blocks
- Silent failures
[Paste the code from Steps 1-3]
Output a report with severity ratings (Critical, High, Medium, Low) and specific fixes.
Example Security Report:
## Critical Issues
### 1. SQL Injection in Product Search
**Location:** `src/controllers/products.controller.ts:24`
**Issue:** User input concatenated directly into SQL query
typescript
// VULNERABLE
const query = SELECT * FROM products WHERE name LIKE '%${search}%';
**Fix:** Use parameterized queries
typescript
const query = 'SELECT * FROM products WHERE name LIKE $1';
await db.query(query, [%${search}%]);
## High Issues
### 2. Missing CSRF Protection
**Location:** `src/index.ts`
**Issue:** No CSRF middleware for state-changing operations
**Fix:** Add csurf middleware
typescript
import csrf from 'csurf';
app.use(csrf({ cookie: true }));
## Medium Issues
### 3. Implicit Any in API Response
**Location:** `src/lib/api-client.ts:8`
**Issue:** Generic `any` type for fetcher function
**Fix:** Add proper type constraints
typescript
async function fetcher>(
endpoint: string,
options?: RequestInit
): Promise { ... }
markdown
Type Safety Report:
## TypeScript Violations
1. `products.controller.ts:45` - Missing return type annotation
2. `auth.middleware.ts:12` - Implicit any in catch block
3. `orders.service.ts:78` - Object possibly undefined
Run `tsc --noEmit` to see full list. Fix before deployment.
Apply all fixes before proceeding.
Step 5: Reality Checker Validates Before Ship
Open a new session and activate Reality Checker mode. Prompt:
Activate Reality Checker mode.
This e-commerce API is ready for production validation.
Run your mandatory reality check process:
1. Verify files exist
2. Cross-reference claimed features with actual code
3. Require screenshot evidence from Playwright tests
4. Review test-results.json for performance metrics
Project URL: http://localhost:3000
Test results: ./public/qa-screenshots/test-results.json
Output: PASS or NEEDS WORK with specific blocking issues.
Reality Check Commands:
# 1. Verify files exist
ls -la src/controllers/ src/services/ src/routes/
ls -la src/components/ src/lib/
# 2. Cross-reference claimed features
grep -r "jwt\|jsonwebtoken" . --include="*.ts" || echo "NO JWT FOUND"
grep -r "bcrypt\|argon2" . --include="*.ts" || echo "NO PASSWORD HASHING FOUND"
grep -r "rateLimit\|express-rate-limit" . --include="*.ts" || echo "NO RATE LIMITING FOUND"
# 3. Run Playwright screenshot capture
npx playwright test --config=qa-playwright.config.ts --grep "@screenshot"
# 4. Review test results
cat public/qa-screenshots/test-results.json
Validation Report Example:
## Reality Check Results
### File Verification: PASS
- All controller files present
- All component files present
### Feature Verification: NEEDS WORK
- JWT authentication: FOUND
- Password hashing: FOUND
- Rate limiting: NOT FOUND (blocking)
### Screenshot Evidence: NEEDS WORK
- Desktop layout: PASS
- Tablet layout: PASS
- Mobile layout: FAIL (product grid broken at 375px)
### Performance Metrics: NEEDS WORK
- Average load time: 2.3s (target: <1s)
- Console errors: 3 (target: 0)
- Failed network requests: 1 (target: 0)
## Final Status: NEEDS WORK
### Blocking Issues:
1. Rate limiting not implemented
2. Mobile layout broken on product list
3. 3 console errors to fix
4. Load time exceeds 1s target
### Non-Blocking:
- Add loading skeletons to order history
- Improve error messages
Fix all blocking issues and rerun the Reality Checker.
Workflow Summary
┌─────────────────────────────────────────────────────────────────┐
│ Backend Architect │
│ → OpenAPI spec, database schema, folder structure │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Database Optimizer │
│ → Index recommendations, missing tables, constraints │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Frontend Developer │
│ → React components, API client, error handling │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Code Reviewer │
│ → Security audit, type safety, error handling gaps │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Reality Checker │
│ → Evidence-based validation, screenshot proof, PASS/FAIL │
└─────────────────────────────────────────────────────────────────┘
Parallel Agent Execution (Advanced)
You can run agents in parallel to save time:
# Terminal 1: Backend Architect
claude "Activate Backend Architect. Design e-commerce API..."
# Terminal 2: Database Optimizer (wait for schema output)
claude "Activate Database Optimizer. Review this schema..."
# Terminal 3: Frontend Developer (wait for API spec)
claude "Activate Frontend Developer. Build React dashboard..."
# Terminal 4: Code Reviewer (wait for code)
claude "Activate Code Reviewer. Review this codebase..."
# All terminals: Reality Checker (final validation)
claude "Activate Reality Checker. Run mandatory checks..."
Parallel execution can reduce total workflow time from 6-8 hours to 2-4 hours.
What You Built
| Deliverable | Agent | Output |
|---|---|---|
| API Design | Backend Architect | OpenAPI spec, database schema, folder structure |
| Schema Optimization | Database Optimizer | Index recommendations, additional tables |
| Frontend | Frontend Developer | React components, API client, error boundaries |
| Security Audit | Code Reviewer | Vulnerability report, type safety fixes |
| Final Validation | Reality Checker | Screenshot evidence, PASS/FAIL certification |
Next Steps
Deploy the API:
- Set up production PostgreSQL with connection pooling
- Configure environment variables for secrets
- Add health check endpoints
- Set up monitoring (Prometheus, Grafana)
Extend the workflow:
- Add Performance Benchmarker agent for load testing
- Add Technical Writer agent for documentation
- Add DevOps Automator agent for CI/CD pipeline
Reuse the pattern:
- Save prompts as templates
- Create a workflow script that chains agent sessions
- Share with your team
Five specialized agents. One complete API. No generic advice.
That’s the power of specialization. Each agent brings domain expertise, checklists, and clear deliverables.
Your turn: pick a project, activate the agents, and ship faster.
Key Takeaways
- Specialized agents outperform generic assistants — Each agent has domain expertise, checklists, and specific deliverables
- Sequential workflow ensures quality — Backend Architect designs, Database Optimizer reviews, Frontend Developer builds, Code Reviewer audits, Reality Checker validates
- Evidence-based approval prevents bugs — Reality Checker requires screenshot proof, grep results, and performance metrics before PASS certification
- Parallel execution reduces total time — Run 4 terminals simultaneously to complete in 2-4 hours instead of 6-8 hours
- Save prompts as templates — Reuse the same agent activations for consistent results across projects
FAQ
What are AI agents for developers?
AI agents are specialized AI assistants with domain expertise. Unlike generic chatbots, agents like Backend Architect or Code Reviewer have specific checklists and produce consistent deliverables.
How do I install agents from The Agency?
Clone the repo at github.com/msitarzewski/agency-agents, then copy .md files to ~/.claude/agents/ for Claude Code or use the install script for other tools.
What is the Reality Checker agent?
Reality Checker is an evidence-based QA agent that refuses to approve work without proof. It requires screenshots, grep results, and performance metrics before giving PASS certification.
Can I run multiple agents in parallel?
Yes. Open multiple terminals and activate different agents in each. Pass deliverables by copying output or using MCP memory for automatic handoffs.
How do I pass context between agents?
Copy output from one agent and paste it as input for the next. For automatic handoffs, use MCP memory to store deliverables that the next agent can recall.
What if an agent says NEEDS WORK?
Fix the blocking issues the agent identified, then re-run the agent. The Reality Checker specifically lists what needs to be fixed before PASS certification.
Do I need all 5 agents for every project?
No. Start with Backend Architect and Code Reviewer for API projects. Add Database Optimizer for complex schemas, Frontend Developer for UI work, and Reality Checker before shipping.
Top comments (0)