Build or update the BlueBubbles external channel plugin for Moltbot (extension package, REST...
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.