Install
$ agentstack add skill-bradtaylorsf-alphaagent-team-api-design ✓ 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 Design Skill
Patterns for designing clean, consistent, and developer-friendly APIs.
REST API Design
URL Structure
# Collection endpoints
GET /api/v1/users # List users
POST /api/v1/users # Create user
# Resource endpoints
GET /api/v1/users/:id # Get user
PUT /api/v1/users/:id # Update user
DELETE /api/v1/users/:id # Delete user
# Nested resources
GET /api/v1/users/:id/posts # Get user's posts
POST /api/v1/users/:id/posts # Create post for user
# Actions (when CRUD doesn't fit)
POST /api/v1/users/:id/activate
POST /api/v1/orders/:id/cancel
HTTP Methods
| Method | Usage | Idempotent | Safe | |--------|-------|------------|------| | GET | Read resource | Yes | Yes | | POST | Create resource | No | No | | PUT | Replace resource | Yes | No | | PATCH | Partial update | No | No | | DELETE | Remove resource | Yes | No |
Status Codes
// Success
200 OK // Successful GET, PUT, PATCH, DELETE
201 Created // Successful POST (resource created)
204 No Content // Successful DELETE (no body)
// Redirection
301 Moved Permanently
304 Not Modified // Cache valid
// Client Errors
400 Bad Request // Invalid input
401 Unauthorized // Not authenticated
403 Forbidden // Not authorized
404 Not Found // Resource doesn't exist
409 Conflict // State conflict (duplicate)
422 Unprocessable // Validation failed
429 Too Many Requests // Rate limited
// Server Errors
500 Internal Error // Unexpected error
502 Bad Gateway // Upstream error
503 Unavailable // Temporarily down
Request/Response Format
// Standard response envelope
interface ApiResponse {
data: T;
meta?: {
pagination?: Pagination;
timestamp: string;
};
}
// List response with pagination
interface ListResponse {
data: T[];
meta: {
pagination: {
page: number;
limit: number;
total: number;
totalPages: number;
};
};
}
// Error response
interface ErrorResponse {
error: {
code: string;
message: string;
details?: Record;
};
}
Query Parameters
# Pagination
GET /api/v1/users?page=1&limit=20
# Filtering
GET /api/v1/users?status=active&role=admin
# Sorting
GET /api/v1/users?sort=createdAt&order=desc
# Field selection
GET /api/v1/users?fields=id,name,email
# Search
GET /api/v1/users?q=john
# Complex filters
GET /api/v1/products?price[gte]=10&price[lte]=100
GET /api/v1/orders?createdAt[gte]=2024-01-01
Versioning
// URL versioning (recommended)
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// Header versioning
// Accept: application/vnd.myapp.v1+json
// Query parameter
// GET /api/users?version=1
GraphQL Design
Schema Design
type Query {
user(id: ID!): User
users(filter: UserFilter, pagination: PaginationInput): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
deleteUser(id: ID!): DeleteUserPayload!
}
type User {
id: ID!
email: String!
name: String!
posts(first: Int, after: String): PostConnection!
createdAt: DateTime!
}
input CreateUserInput {
email: String!
name: String!
password: String!
}
type CreateUserPayload {
user: User
errors: [Error!]
}
type Error {
field: String
message: String!
}
Pagination (Relay-style)
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
Error Handling
# Return errors in payload, not as GraphQL errors
type CreateUserPayload {
user: User
userErrors: [UserError!]!
}
type UserError {
field: [String!]
message: String!
code: ErrorCode!
}
enum ErrorCode {
INVALID_INPUT
NOT_FOUND
UNAUTHORIZED
CONFLICT
}
API Documentation
OpenAPI (Swagger)
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: List users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
components:
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
required:
- id
- email
- name
Rate Limiting
// Express rate limiter
import rateLimit from 'express-rate-limit';
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: {
error: 'Too many requests, please try again later',
},
standardHeaders: true, // Return rate limit info in headers
legacyHeaders: false,
});
app.use('/api/', apiLimiter);
// Per-user rate limiting
const userLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 30,
keyGenerator: (req) => req.user?.id || req.ip,
});
Caching
// Cache headers
res.set({
'Cache-Control': 'public, max-age=300', // 5 minutes
'ETag': generateETag(data),
});
// Conditional requests
app.get('/users/:id', (req, res) => {
const user = getUser(req.params.id);
const etag = generateETag(user);
if (req.headers['if-none-match'] === etag) {
return res.status(304).end();
}
res.set('ETag', etag);
res.json({ data: user });
});
Integration
Used by:
backend-developeragent- Express/Node.js stack skills
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.