BAiSEDagent

api-design

0
0
# Install this skill:
npx skills add BAiSEDagent/openclaw-skills --skill "api-design"

Install specific skill from multi-skill repository

# Description

REST and JSON-RPC API design patterns. Error handling, rate limiting, versioning, auth. Use when building or reviewing APIs.

# SKILL.md


name: api-design
description: "REST and JSON-RPC API design patterns. Error handling, rate limiting, versioning, auth. Use when building or reviewing APIs."
metadata:
openclaw:
emoji: "πŸ”§"


API Design Patterns

Patterns for building production APIs β€” REST, JSON-RPC, error handling, auth.

REST Conventions

URL Structure

GET    /api/v1/agents          # List
POST   /api/v1/agents          # Create
GET    /api/v1/agents/:id      # Read
PATCH  /api/v1/agents/:id      # Update (partial)
DELETE /api/v1/agents/:id      # Delete

GET    /api/v1/agents/:id/payments  # Nested resources

Response Format (Consistent)

// Success
{ "success": true, "data": { ... } }

// Error
{ "success": false, "error": "Description", "code": "INVALID_INPUT", "hint": "How to fix" }

// List with pagination
{ "success": true, "data": [...], "pagination": { "total": 100, "page": 1, "limit": 25 } }

Status Codes

Code When
200 Success (GET, PATCH)
201 Created (POST)
204 Deleted (DELETE, no body)
400 Invalid input
401 Not authenticated
402 Payment required (x402!)
403 Not authorized
404 Not found
409 Conflict (duplicate)
429 Rate limited
500 Server error

Authentication

API Key (Agent-to-Agent)

// Header: x-agent-key (NOT x-api-key β€” our convention)
function authMiddleware(req, res, next) {
  const key = req.headers['x-agent-key'];
  if (!key) return res.status(401).json({ error: 'Missing x-agent-key header' });

  const agent = await findAgentByKey(key);
  if (!agent) return res.status(401).json({ error: 'Invalid agent key' });

  req.agent = agent;
  next();
}

JWT (Session-based)

// For human users with login sessions
const token = jwt.sign({ userId, role }, SECRET, { expiresIn: '24h' });
// Verify: jwt.verify(token, SECRET)

Rate Limiting

import rateLimit from 'express-rate-limit';

// Global: 100 req/min
app.use(rateLimit({ windowMs: 60_000, max: 100 }));

// Per-endpoint: stricter for writes
app.post('/api/v1/posts', rateLimit({ windowMs: 1800_000, max: 1 }), createPost);

Response when limited:

{
  "success": false,
  "error": "Rate limit exceeded",
  "retry_after_seconds": 45
}

Validation

// Validate at the boundary, trust internally
function validateAgentRegistration(body: unknown) {
  if (!body || typeof body !== 'object') throw new ValidationError('Body required');
  const { name, capabilities } = body as any;
  if (!name || typeof name !== 'string') throw new ValidationError('name is required');
  if (name.length > 50) throw new ValidationError('name must be ≀50 chars');
  if (capabilities && !Array.isArray(capabilities)) throw new ValidationError('capabilities must be array');
  return { name: name.trim(), capabilities: capabilities || [] };
}

Error Handling

// Centralized error handler
app.use((err, req, res, next) => {
  if (err instanceof ValidationError) {
    return res.status(400).json({ success: false, error: err.message, code: 'VALIDATION_ERROR' });
  }
  console.error(err);
  res.status(500).json({ success: false, error: 'Internal server error', code: 'INTERNAL_ERROR' });
});

JSON-RPC (for MCP/A2A)

// Request
{ "jsonrpc": "2.0", "id": "1", "method": "tools/call", "params": { "name": "resolve_ens", "arguments": { "domain": "baisedagent.base.eth" } } }

// Success response
{ "jsonrpc": "2.0", "id": "1", "result": { "address": "0x..." } }

// Error response
{ "jsonrpc": "2.0", "id": "1", "error": { "code": -32600, "message": "Invalid request" } }

Security Headers

import helmet from 'helmet';
app.use(helmet());
app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') || '*' }));

Versioning

  • URL-based: /api/v1/... (preferred β€” explicit, cacheable)
  • Header-based: Accept: application/vnd.agenthq.v1+json (alternative)
  • Never break v1 β€” add v2 for breaking changes

Cross-References

  • x402: The 402 response IS an API pattern
  • testing-patterns: Test every endpoint
  • deployment-ops: Deploy the API
  • monitoring-alerting: Monitor API health

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.