Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Design, build, test, document, and secure production-grade APIs. Covers the full lifecycle from schema design through deployment, monitoring, and versioning....
Design, build, test, document, and secure production-grade APIs. Covers the full lifecycle from schema design through deployment, monitoring, and versioning....
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
Design, build, test, document, secure, and monitor production-grade APIs. Not just curl commands β a complete engineering methodology.
Designing a new API (REST, GraphQL, or gRPC) Reviewing an existing API for quality, consistency, or security Generating or validating OpenAPI/Swagger specs Building comprehensive test suites (unit, integration, contract, load) Debugging production API issues Planning API versioning and deprecation Setting up monitoring, rate limiting, and error handling
Always design before coding. The spec IS the contract. Resource Modeling Map your domain to resources using this template: # api-design.yaml service: order-management base_path: /api/v1 resources: - name: orders path: /orders description: Customer purchase orders identifier: order_id (UUID) parent: null operations: [list, create, get, update, cancel] sub_resources: - name: line_items path: /orders/{order_id}/items operations: [list, add, update, remove] - name: payments path: /orders/{order_id}/payments operations: [list, create, get, refund] states: [draft, confirmed, processing, shipped, delivered, cancelled] transitions: - from: draft β to: confirmed (action: confirm) - from: confirmed β to: processing (action: process) - from: processing β to: shipped (action: ship) - from: shipped β to: delivered (action: deliver) - from: [draft, confirmed] β to: cancelled (action: cancel) Naming Conventions Checklist RuleGoodBadPlural nouns for collections/users/user, /getUsersKebab-case for multi-word/line-items/lineItems, /line_itemsNo verbs in URLsPOST /orders/createOrderNest for ownership/users/123/orders/orders?user=123 (for primary relationship)Max 3 levels deep/users/123/orders/users/123/orders/456/items/789/optionsFilter via query params/orders?status=active/active-ordersActions as sub-resourcePOST /orders/123/cancelPATCH /orders/123 {cancelled:true} HTTP Methods β Decision Matrix Need to... β Method Idempotent? Safe? Get a resource or collection β GET Yes Yes Create a new resource β POST No No Full replace of a resource β PUT Yes No Partial update of a resource β PATCH No* No Remove a resource β DELETE Yes No Check if resource exists β HEAD Yes Yes List allowed methods β OPTIONS Yes Yes * PATCH can be idempotent if using JSON Merge Patch Status Code Decision Tree Success? βββ Created something new? β 201 Created (Location header) βββ Accepted for async processing? β 202 Accepted (include status URL) βββ No body to return? β 204 No Content βββ Returning data? β 200 OK Client error? βββ Malformed request syntax? β 400 Bad Request βββ No/invalid credentials? β 401 Unauthorized βββ Valid credentials but insufficient permissions? β 403 Forbidden βββ Resource doesn't exist? β 404 Not Found βββ Method not allowed on resource? β 405 Method Not Allowed βββ Conflict with current state? β 409 Conflict βββ Resource permanently gone? β 410 Gone βββ Validation failed? β 422 Unprocessable Entity βββ Too many requests? β 429 Too Many Requests (Retry-After header) βββ Precondition failed (etag mismatch)? β 412 Precondition Failed Server error? βββ Unexpected failure? β 500 Internal Server Error βββ Upstream dependency failed? β 502 Bad Gateway βββ Temporarily overloaded? β 503 Service Unavailable (Retry-After) βββ Upstream timeout? β 504 Gateway Timeout
Standard Response Envelope // Success (single resource) { "data": { "id": "ord_abc123", "status": "confirmed", ... }, "meta": { "request_id": "req_xyz789" } } // Success (collection) { "data": [ ... ], "meta": { "request_id": "req_xyz789" }, "pagination": { "total": 142, "page": 2, "per_page": 20, "total_pages": 8, "next": "/api/v1/orders?page=3&per_page=20", "prev": "/api/v1/orders?page=1&per_page=20" } } // Error { "error": { "code": "VALIDATION_FAILED", "message": "Request validation failed", "details": [ { "field": "email", "message": "Must be a valid email address", "code": "INVALID_FORMAT" }, { "field": "age", "message": "Must be at least 18", "code": "MIN_VALUE", "min": 18 } ] }, "meta": { "request_id": "req_xyz789" } } Pagination Patterns β When to Use Which PatternUse WhenProsConsOffset ?page=2&per_page=20Simple UI pagination, small datasetsEasy to implement, page jumpingDrift on inserts, slow on large offsetsCursor ?after=eyJ...&limit=20Infinite scroll, real-time feeds, large datasetsConsistent, performantNo page jumping, opaque cursorsKeyset ?created_after=2024-01-01&limit=20Time-series data, logsFast, transparentRequires sortable field, no count Filtering, Sorting, Field Selection # Filtering GET /orders?status=active&created_after=2024-01-01&total_min=100 # Sorting (prefix - for descending) GET /orders?sort=-created_at,total # Field selection (reduce payload) GET /orders?fields=id,status,total,customer.name # Search GET /products?q=wireless+headphones # Combined GET /orders?status=active&sort=-created_at&fields=id,status,total&page=1&per_page=10
For each resource in your design, generate a complete spec: openapi: 3.1.0 info: title: Order Management API version: 1.0.0 description: | Order lifecycle management. ## Authentication All endpoints require Bearer token authentication. ## Rate Limits - Standard: 100 req/min - Bulk operations: 10 req/min contact: name: API Support email: api@example.com license: name: MIT servers: - url: https://api.example.com/v1 description: Production - url: https://staging-api.example.com/v1 description: Staging paths: /orders: get: operationId: listOrders summary: List orders tags: [Orders] parameters: - $ref: '#/components/parameters/PageParam' - $ref: '#/components/parameters/PerPageParam' - name: status in: query schema: $ref: '#/components/schemas/OrderStatus' - name: created_after in: query schema: type: string format: date-time responses: '200': description: Order list content: application/json: schema: $ref: '#/components/schemas/OrderListResponse' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createOrder summary: Create an order tags: [Orders] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateOrderRequest' examples: basic: summary: Basic order value: customer_id: "cust_abc" items: - product_id: "prod_xyz" quantity: 2 responses: '201': description: Order created headers: Location: schema: type: string description: URL of created order content: application/json: schema: $ref: '#/components/schemas/OrderResponse' '422': $ref: '#/components/responses/ValidationError' components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT parameters: PageParam: name: page in: query schema: { type: integer, minimum: 1, default: 1 } PerPageParam: name: per_page in: query schema: { type: integer, minimum: 1, maximum: 100, default: 20 } responses: Unauthorized: description: Missing or invalid authentication content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' ValidationError: description: Request validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' security: - BearerAuth: []
#CheckScore1Every endpoint has operationId/22All parameters documented with types + constraints/23Request bodies have examples/24All error responses documented (400, 401, 403, 404, 422, 429, 500)/25Shared schemas use $ref (DRY)/26Pagination parameters standardized/27Security scheme defined + applied globally/28Description includes auth, rate limits, versioning info/29Response headers documented (Location, Retry-After, ETag)/210Enums used for fixed value sets/2 Score: ___/20 (Target: 16+)
Every endpoint MUST validate before processing: Validation Order: 1. Content-Type header (reject non-JSON early) 2. Authentication (401 before wasting cycles) 3. Authorization (403 - does this user have access?) 4. Path parameters (404 - does the resource exist?) 5. Query parameters (400 - valid types/ranges?) 6. Request body schema (422 - valid structure?) 7. Business rules (422 - valid state transition?)
Define a consistent error code enum for your API: # Authentication & Authorization AUTH_REQUIRED β No credentials provided AUTH_INVALID β Invalid/expired credentials AUTH_INSUFFICIENT β Valid credentials, wrong permissions AUTH_RATE_LIMITED β Too many auth attempts # Validation VALIDATION_FAILED β Generic validation error (see details array) INVALID_FORMAT β Field format wrong (email, UUID, etc.) REQUIRED_FIELD β Required field missing OUT_OF_RANGE β Value outside allowed range INVALID_ENUM β Value not in allowed set # Resource NOT_FOUND β Resource doesn't exist ALREADY_EXISTS β Duplicate (unique constraint) CONFLICT β State conflict (e.g., already cancelled) GONE β Resource permanently deleted # Business Logic INSUFFICIENT_FUNDS β Payment-related QUOTA_EXCEEDED β Usage limit reached FEATURE_DISABLED β Feature flag off DEPENDENCY_FAILED β Upstream service error # System INTERNAL_ERROR β Unexpected server error SERVICE_UNAVAILABLE β Temporarily down TIMEOUT β Request took too long
For non-idempotent operations (POST), require an idempotency key: Request: POST /orders Idempotency-Key: ord_req_abc123 Server behavior: 1. Check if Idempotency-Key was seen before 2. If yes β return cached response (same status, same body) 3. If no β process request, cache response for 24h 4. Key format: client-generated UUID or meaningful string
Standard headers to include: X-RateLimit-Limit: 100 # Max requests per window X-RateLimit-Remaining: 67 # Remaining in current window X-RateLimit-Reset: 1706886400 # Unix timestamp when window resets Retry-After: 30 # Seconds to wait (on 429) Rate limit tiers: TierLimitWindowUse CaseStandard100/minSlidingNormal API callsBulk10/minSlidingBatch operationsSearch30/minSlidingFull-text searchAuth5/minFixedLogin attemptsWebhook1000/minSlidingIncoming webhooks
/ E2E \ β 5-10 critical user flows / Contract \ β Schema validation, backward compat / Integration \ β Database, external services, auth / Unit Tests \ β Business logic, validation, transforms βΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎβΎ
For EVERY endpoint, test these scenarios: endpoint: POST /orders tests: happy_path: - Creates order with valid data β 201 - Returns created resource with ID - Location header points to new resource - Timestamps are set (created_at, updated_at) validation: - Missing required fields β 422 with field-level errors - Invalid field types (string where int expected) β 422 - Empty body β 400 - Invalid Content-Type β 415 - Extra unknown fields β ignored or 422 (pick one, be consistent) - Boundary values (min/max length, 0, negative, empty string vs null) authentication: - No token β 401 - Expired token β 401 - Invalid token β 401 - Valid token, wrong scope β 403 authorization: - User accessing own resource β 200 - User accessing other's resource β 403 or 404 (security choice) - Admin accessing any resource β 200 edge_cases: - Duplicate creation (same idempotency key) β same 201 response - Concurrent creation race condition β one wins, one gets 409 - Resource at max relationships β 422 - Unicode in text fields β handled correctly - Very long strings β 422 with max length error - SQL injection in params β no effect (parameterized queries) - XSS in text fields β stored safely, escaped on output performance: - Response time < 200ms (p95) - List endpoint with 10K records β paginated, < 500ms - Bulk operation timeout handling
# === Setup === BASE="https://api.example.com/v1" TOKEN="your_bearer_token" alias api='curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"' # === CRUD Lifecycle Test === # Create ORDER=$(api -X POST "$BASE/orders" -d '{"customer_id":"cust_1","items":[{"product_id":"prod_1","qty":2}]}') ORDER_ID=$(echo "$ORDER" | jq -r '.data.id') echo "Created: $ORDER_ID" # Read api "$BASE/orders/$ORDER_ID" | jq . # Update api -X PATCH "$BASE/orders/$ORDER_ID" -d '{"notes":"Rush order"}' | jq . # List with filters api "$BASE/orders?status=draft&sort=-created_at&per_page=5" | jq . # Action (state transition) api -X POST "$BASE/orders/$ORDER_ID/confirm" | jq . # Delete curl -s -o /dev/null -w "%{http_code}" -X DELETE -H "Authorization: Bearer $TOKEN" "$BASE/orders/$ORDER_ID" # === Error Testing === # No auth curl -s "$BASE/orders" | jq .error # Invalid body api -X POST "$BASE/orders" -d '{"invalid": true}' | jq .error # Not found api "$BASE/orders/nonexistent" | jq .error # === Performance === # Timing breakdown curl -s -o /dev/null -w "DNS:%{time_namelookup} TCP:%{time_connect} TLS:%{time_appconnect} TTFB:%{time_starttransfer} Total:%{time_total}\n" -H "Authorization: Bearer $TOKEN" "$BASE/orders" # Quick load test (50 requests, 10 concurrent) seq 50 | xargs -P10 -I{} curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" -H "Authorization: Bearer $TOKEN" "$BASE/orders"
Validate your API hasn't broken backward compatibility: # contract-tests.yaml contract: name: Order API Contract version: 1.0.0 rules: # These changes are SAFE (non-breaking) safe: - Adding new optional fields to responses - Adding new endpoints - Adding new optional query parameters - Adding new enum values (if clients handle unknown) - Widening a constraint (min: 5 β min: 1) # These changes are BREAKING breaking: - Removing a response field - Renaming a response field - Changing a field type - Adding a new required request field - Removing an endpoint - Narrowing a constraint (max: 100 β max: 50) - Changing error response format - Removing an enum value # Verify after every change checks: - All existing fields still present in responses - All existing field types unchanged - All existing required fields still required (no more, no fewer) - Default values unchanged - Error format unchanged
authentication: - [ ] All endpoints require auth (except /health, /docs, public webhooks) - [ ] Tokens expire (short-lived access + long-lived refresh) - [ ] Token rotation supported - [ ] Failed auth returns 401 with no info leakage - [ ] API keys are hashed in storage (never plain text) authorization: - [ ] Resource-level checks (user can only access their data) - [ ] Endpoint-level checks (role-based access) - [ ] No IDOR vulnerabilities (can't guess other users' resource IDs) - [ ] Admin endpoints separately protected - [ ] Webhook endpoints verify signatures input_validation: - [ ] All inputs validated server-side (never trust client) - [ ] SQL injection prevented (parameterized queries only) - [ ] NoSQL injection prevented - [ ] Path traversal prevented - [ ] Request size limited (body, headers, URL length) - [ ] File upload types restricted and scanned output_security: - [ ] No sensitive data in responses (passwords, tokens, internal IDs) - [ ] No stack traces in production errors - [ ] Consistent error format (no info leakage in different error types) - [ ] PII redacted in logs transport: - [ ] HTTPS only (HTTP redirects to HTTPS) - [ ] HSTS header set - [ ] TLS 1.2+ required - [ ] CORS configured restrictively (specific origins, not *) headers: - [ ] X-Content-Type-Options: nosniff - [ ] X-Frame-Options: DENY - [ ] Content-Security-Policy set - [ ] No Server version header - [ ] Cache-Control: no-store for sensitive endpoints
# Restrictive (recommended) cors: origins: - https://app.example.com - https://admin.example.com methods: [GET, POST, PUT, PATCH, DELETE] headers: [Authorization, Content-Type, X-Request-ID] credentials: true max_age: 3600 # Common mistakes to avoid: # β Access-Control-Allow-Origin: * (with credentials) # β Reflecting Origin header without validation # β Allowing all methods/headers
StrategyExampleProsConsUse WhenURL path/v1/ordersExplicit, easy routingURL pollutionPublic APIs, multiple major versionsHeaderAPI-Version: 2024-01Clean URLsHidden, harder to testInternal APIsQuery param?version=2Easy to testPollutes paramsQuick prototypesDate-based2024-01-15Clear timelineMany versionsStripe-style APIs Recommended: URL path for major versions, header for minor variations.
Timeline: 1. T+0: Announce deprecation (docs, changelog, email) 2. T+0: Add Deprecation + Sunset headers to old endpoints 3. T+30d: Log warnings for old endpoint usage 4. T+60d: Email heavy users of old endpoint directly 5. T+90d: Return 299 warning header 6. T+180d: Shut down old endpoint (410 Gone) Headers: Deprecation: true Sunset: Sat, 01 Jun 2025 00:00:00 GMT Link: <https://api.example.com/v2/orders>; rel="successor-version"
# Migrating from v1 to v2 ## Breaking Changes 1. `user.name` split into `user.first_name` + `user.last_name` 2. Pagination changed from offset to cursor-based 3. Error format updated (see new schema) ## Step-by-Step Migration 1. Update your client SDK to v2 (`npm install @example/sdk@2`) 2. Update response parsing for split name fields 3. Replace `?page=N` with `?after=cursor` pagination 4. Update error handling for new error format ## Compatibility Mode Set `X-Compat-Mode: v1` header to get v1-style responses from v2 endpoints. Available until 2025-06-01.
availability: - Uptime percentage (target: 99.9% = 8.7h downtime/year) - Health check status (/health endpoint) - Error rate (5xx / total requests) performance: - p50 latency (target: < 100ms) - p95 latency (target: < 500ms) - p99 latency (target: < 1000ms) - Throughput (requests/second) - Time to first byte (TTFB) business: - Requests per endpoint (usage patterns) - Unique API consumers/day - Error rate by endpoint - Rate limit hits/day - Authentication failures/day infrastructure: - Database query time (p95) - Connection pool utilization - Memory/CPU per instance - Queue depth (async operations)
Every request should log: { "timestamp": "2024-01-15T10:30:00.000Z", "level": "info", "request_id": "req_abc123", "method": "POST", "path": "/api/v1/orders", "status": 201, "duration_ms": 45, "user_id": "usr_xyz", "ip": "203.0.113.1", "user_agent": "MyApp/2.0", "request_size": 256, "response_size": 1024 }
// GET /health β for load balancers (simple) { "status": "ok" } // GET /health/detailed β for monitoring (authenticated) { "status": "degraded", "version": "1.5.2", "uptime_seconds": 86400, "checks": { "database": { "status": "ok", "latency_ms": 5 }, "redis": { "status": "ok", "latency_ms": 2 }, "external_payment_api": { "status": "degraded", "latency_ms": 2500, "error": "timeout" }, "disk": { "status": "ok", "free_gb": 45.2 } } }
When reviewing an existing API, score across these dimensions:
DimensionWeightCriteriaScoreDesign Consistency20%Naming conventions, HTTP methods, status codes, URL structure/20Documentation15%OpenAPI spec, examples, error docs, changelog/15Error Handling15%Consistent format, helpful messages, proper codes, no leakage/15Security20%Auth, input validation, CORS, headers, no IDOR/20Performance15%Latency targets met, pagination, caching headers, N+1 prevented/15Developer Experience15%SDK quality, sandbox available, onboarding time, rate limit clarity/15 Score: ___/100 RatingScoreActionπ’ Excellent85-100Minor improvements onlyπ‘ Good70-84Address gaps before next major releaseπ Needs Work50-69Prioritize improvements, create tech debt ticketsπ΄ Critical<50Stop feature work, fix fundamentals first
# Good: clear types, nullable where appropriate, connections for lists type Order { id: ID! status: OrderStatus! customer: Customer! items(first: Int, after: String): ItemConnection! total: Money! createdAt: DateTime! updatedAt: DateTime! } type Money { amount: Int! # cents, not dollars (avoid float) currency: Currency! } enum OrderStatus { DRAFT CONFIRMED PROCESSING SHIPPED DELIVERED CANCELLED } # Mutations return the modified resource + errors type CreateOrderPayload { order: Order errors: [UserError!]! } type UserError { field: [String!] message: String! code: ErrorCode! }
Anti-PatternProblemFixNo depth limitQuery bombsLimit depth to 5-7 levelsNo complexity limitExpensive queriesAssign cost per field, cap at 1000N+1 queriesPerformance deathUse DataLoader patternNo persisted queriesSecurity riskWhitelist queries in productionExposing internal IDsLeaks implementationUse opaque global IDsNo paginationMemory explosionUse Relay Connection spec
Always store and return UTC (ISO 8601: 2024-01-15T10:30:00Z) Accept timezone in input, convert to UTC immediately Never use local server time
Set Content-Length limits (e.g., 1MB default, 10MB for uploads) Use streaming for file uploads (multipart/form-data) Compress responses (Accept-Encoding: gzip) For very large exports β return 202 + poll status endpoint
If using async processing, always return 202 + status URL Include estimated completion time when possible Client should poll with exponential backoff
Use ETags for optimistic concurrency: GET returns ETag: "v1" header PUT/PATCH sends If-Match: "v1" header Server returns 412 if resource changed since
Include event type, timestamp, and full resource in payload Sign payloads (HMAC-SHA256) Expect retries (make handlers idempotent) Return 200 quickly, process async Include webhook ID for deduplication
RequestAction"Design an API for [domain]"Run Phase 1 resource modeling + naming"Generate OpenAPI spec"Run Phase 2 with full components"Review this API"Run Phase 8 scoring rubric"Write tests for [endpoint]"Run Phase 4 endpoint checklist"Security audit this API"Run Phase 5 security checklist"How should I version this?"Run Phase 6 decision matrix"Debug this API issue"Check Phase 7 logging + health patterns"Design GraphQL schema for [domain]"Run GraphQL section
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.