Install
$ agentstack add skill-bradtaylorsf-alphaagent-team-api-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
API Patterns Skill
Quick Reference
Use when: Building REST APIs, implementing authentication, handling errors, validating inputs
Key Patterns:
- Request validation
- Standardized error responses
- Authentication middleware
- Rate limiting
- Pagination
- API documentation
1. Request Validation
Always validate incoming requests at the boundary.
Pattern with schema validation:
// Define schema for expected input
const CreateUserSchema = {
email: 'string, email format, required',
password: 'string, min 12 chars, required',
name: 'string, 2-100 chars, required',
age: 'number, integer, min 18, optional'
};
// Validate in route handler
function createUserHandler(req, res) {
const validation = validateSchema(CreateUserSchema, req.body);
if (!validation.success) {
return res.status(400).json({
error: 'Validation failed',
details: validation.errors
});
}
// Proceed with validated data
const user = await createUser(validation.data);
res.status(201).json(user);
}
Key Points:
- Validate at API boundary, not deep in business logic
- Return specific error messages
- Use 400 status code for validation failures
2. Standardized Error Responses
Use consistent error format across all endpoints.
// Error response structure
interface ErrorResponse {
error: string; // Human-readable message
code?: string; // Machine-readable error code
details?: unknown; // Additional context (validation errors, etc.)
}
// Custom error class
class AppError extends Error {
constructor(
message: string,
public statusCode: number = 500,
public code?: string,
public details?: unknown
) {
super(message);
}
}
// Usage
throw new AppError('User not found', 404, 'USER_NOT_FOUND');
throw new AppError('Validation failed', 400, 'VALIDATION_ERROR', errors);
Error Handler Pattern:
function errorHandler(err, req, res, next) {
// Known application errors
if (err instanceof AppError) {
return res.status(err.statusCode).json({
error: err.message,
code: err.code,
details: err.details
});
}
// Log unexpected errors (don't expose to user)
console.error('Unexpected error:', err);
res.status(500).json({
error: 'Internal server error'
});
}
3. Authentication Middleware
Protect routes with authentication middleware.
// Auth middleware pattern
function requireAuth(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new AppError('Authentication required', 401, 'NO_TOKEN');
}
try {
const decoded = verifyToken(token);
req.userId = decoded.userId;
next();
} catch (err) {
throw new AppError('Invalid token', 401, 'INVALID_TOKEN');
}
}
// Optional auth (for routes that work with or without auth)
function optionalAuth(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (token) {
try {
const decoded = verifyToken(token);
req.userId = decoded.userId;
} catch {
// Ignore invalid tokens in optional auth
}
}
next();
}
// Usage
router.get('/api/profile', requireAuth, getProfileHandler);
router.get('/api/posts', optionalAuth, getPostsHandler);
4. Rate Limiting
Protect endpoints from abuse.
// General rate limit
const generalLimiter = {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // 100 requests per window
};
// Strict limit for auth endpoints
const authLimiter = {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // Only 5 attempts
skipSuccessfulRequests: true
};
// Apply to routes
app.use('/api/', rateLimitMiddleware(generalLimiter));
router.post('/api/auth/login', rateLimitMiddleware(authLimiter), loginHandler);
5. Pagination
Standard pagination for list endpoints.
// Pagination parameters
const DEFAULT_PAGE = 1;
const DEFAULT_LIMIT = 20;
const MAX_LIMIT = 100;
function parsePagination(query) {
const page = Math.max(1, parseInt(query.page) || DEFAULT_PAGE);
const limit = Math.min(MAX_LIMIT, Math.max(1, parseInt(query.limit) || DEFAULT_LIMIT));
const offset = (page - 1) * limit;
return { page, limit, offset };
}
// Response format
function paginatedResponse(data, total, page, limit) {
return {
data,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
hasNext: page 1
}
};
}
// Usage in handler
async function listUsersHandler(req, res) {
const { page, limit, offset } = parsePagination(req.query);
const [users, total] = await Promise.all([
db.users.findMany({ skip: offset, take: limit }),
db.users.count()
]);
res.json(paginatedResponse(users, total, page, limit));
}
6. API Response Format
Use consistent response structure.
// Success response
{
data: T, // The requested resource(s)
meta?: {
pagination?: {...}, // For lists
timestamp: string // ISO timestamp
}
}
// Error response
{
error: string, // Human-readable message
code?: string, // Machine-readable code
details?: unknown // Additional context
}
7. HTTP Status Codes
Use appropriate status codes:
| Code | Meaning | When to Use | |------|---------|-------------| | 200 | OK | Successful GET, PUT, PATCH | | 201 | Created | Successful POST (resource created) | | 204 | No Content | Successful DELETE | | 400 | Bad Request | Validation errors, malformed request | | 401 | Unauthorized | Missing or invalid authentication | | 403 | Forbidden | Authenticated but not authorized | | 404 | Not Found | Resource doesn't exist | | 409 | Conflict | Resource conflict (duplicate, etc.) | | 429 | Too Many Requests | Rate limit exceeded | | 500 | Internal Error | Unexpected server error |
8. RESTful Resource Naming
Follow conventions:
GET /api/resources- List all (with pagination)GET /api/resources/:id- Get onePOST /api/resources- Create newPUT /api/resources/:id- Replace entirelyPATCH /api/resources/:id- Partial updateDELETE /api/resources/:id- Delete
Nested resources:
GET /api/users/:userId/posts- User's postsPOST /api/users/:userId/posts- Create post for user
Checklist for New Endpoints
- [ ] Input validation with schema
- [ ] Authentication check (if protected)
- [ ] Authorization check (if resource-specific)
- [ ] Rate limiting configured
- [ ] Error handling with appropriate codes
- [ ] Consistent response format
- [ ] Pagination for lists
- [ ] Documentation/comments
- [ ] Tests covering success and error cases
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: bradtaylorsf
- Source: bradtaylorsf/alphaagent-team
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.