eliasoulkadi/shokunin/api-forge

Claude Code and agent skill by eliasoulkadi/shokunin

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Design REST/GraphQL APIs with OpenAPI 3.1, error handling, pagination, rate limiting, webhooks, and idempotency. Use when user asks to design an API, create endpoints, define REST/GraphQL schema, or generate OpenAPI spec. Do NOT use for database schema design, frontend API integration, or non-HTTP protocols (gRPC, WebSocket, MQTT).

Install

npx vskill@latest install eliasoulkadi/shokunin/api-forge

SKILL.md

API Forge

Design APIs that developers love. Based on patterns from Stripe, GitHub, Twilio, Slack, and the OpenAPI 3.1 specification.

Sub-Commands

CommandCategoryDescription
designBuildDesign an API from user requirements. Generate OpenAPI 3.1 spec.
endpointBuildDesign a single endpoint with all methods, parameters, responses, and error codes.
auditEvaluateAudit an existing API against design rules, security checklist, and anti-patterns.
documentDocumentGenerate API documentation from OpenAPI spec or route handlers.
extractDocumentExtract OpenAPI spec from existing route handlers.
webhookBuildDesign webhook delivery, retry, and signature verification.

Workflow

Step 1: Determine API type
TypeUse CaseSpec
RESTCRUD, resource-orientedOpenAPI 3.1
GraphQLComplex queries, multiple resourcesSchema Definition Language
WebhookEvent-driven, async notificationsStandard webhooks (Stripe pattern)
Step 2: Define resources and naming
PatternExampleNotes
Nouns, plural/users, /ordersNever verbs
Nested (max 2 levels)/users/{id}/ordersFlat preferred over deep nesting
Actions as sub-resources/orders/{id}/cancelOnly for non-CRUD operations
Query for filters/users?role=adminNot /users/admins
kebab-case for paths/order-itemsNot /orderItems
snake_case for fieldsfirst_nameNot firstName in JSON:API
Step 3: Map HTTP methods
MethodPurposeIdempotentSafeBody
GETRead resourceYesYesNo
POSTCreate resourceNoNoYes
PUTFull replaceYesNoYes
PATCHPartial updateNoNoYes
DELETERemove resourceYesNoOptional
Step 4: Design response format

Stripe-style standard envelope:

json
{
"data": {},
"meta": {
"page": 1,
"per_page": 25,
"total": 100
},
"error": null,
"request_id": "req_abc123"
}

If using JSON:API or GraphQL, use their standard envelopes instead.

Step 5: Implement pagination

Cursor-based for production. Page-based only for admin/internal tools.

json
GET /items?cursor=abc123&limit=25
{
"data": [...],
"meta": {
"next_cursor": "def456",
"has_more": true
}
}

Cursor must be opaque (base64-encoded compound key). Never expose internal IDs. Maximum limit: 100. Default: 25.

Error Handling

Every error response includes:

  • code: machine-readable error code (VALIDATION_ERROR, NOT_FOUND, RATE_LIMITED)
  • message: human-readable summary, max 150 chars
  • details: array of field-level errors for validation
  • request_id: UUIDv4 for debugging correlation
  • docs_url: link to error documentation (optional, strongly recommended)
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": [
{ "field": "email", "code": "required", "message": "Email is required" }
],
"request_id": "req_a1b2c3d4e5f6",
"docs_url": "https://docs.example.com/errors/validation"
}
}
Status codes — exact mapping
CodeWhenWhat to return
200Success (GET, PUT, PATCH)Resource + meta
201Created (POST)Created resource + Location header
204No content (DELETE)Empty body
400Validation errorError details + fields
401Missing/invalid authGeneric message. Never reveal which part of auth failed.
403Insufficient permissionsGeneric message
404Resource not foundMinimal. Don't reveal if the resource ever existed.
409Conflict (duplicate, stale version)Details of conflicting field
422Unprocessable entityValidation details
429Rate limitedRetry-After header (seconds)
500Internal errorGeneric message. No stack traces. No internal state.
502Downstream failure"Service temporarily unavailable"
503Maintenance / overloadRetry-After header

Rate Limiting

Algorithm decision
AlgorithmBest forBehavior
Token BucketGeneral purpose, bursts allowedTokens refill at configurable rate. Allows bursts up to bucket size.
Sliding WindowStrict fairness, multi-tenantCounts requests in rolling time window. No burst edge at boundaries.
Fixed WindowSimple, non-criticalResets at interval. Budget edge problem at boundaries.

Default: Token Bucket.

Headers (every response)
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1700000000

Return 429 Too Many Requests with Retry-After header when exceeded.

Rate limit tiers (exact values)
TierRequestsWindowPer
Anonymous6060sIP
Authenticated100060sUser ID + endpoint group
Critical endpoints515minIP + identifier

Critical: login (5/15min per IP+username), password reset (3/60min per email), MFA (3/15min per user).

Versioning

StrategyExampleWhenRisk
URL path/v1/usersDefault for REST APIsURL pollution
HeaderAccept: application/vnd.api+json;version=2Clean URLs neededHarder to discover
Query param/users?version=2Simple, transitionalCache poisoning risk

Prefer URL path for public APIs. Deprecate with sunset headers. 6-month migration window minimum.

Deprecation: true
Sunset: Sat, 12 May 2027 00:00:00 GMT

Webhooks

Delivery format (Stripe pattern)
json
{
"id": "wh_abc123",
"type": "order.created",
"created": 1700000000,
"data": {
"id": "order_456",
"status": "paid",
"total": 2999
}
}
Delivery protocol
  • Retry: exponential backoff (1s, 2s, 4s, 8s, 16s, 32s…)
  • Max retries: 3. Max TTL: 24 hours.
  • Expect 200 response within 5 seconds.
  • Signature: HMAC-SHA256.
Signature verification (exact implementation)
X-Webhook-Signature: t=1700000000,v1=abc123def456...
typescript
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const [timestampStr, signatures] = signature.split(',').map(s => s.trim())
const timestamp = timestampStr.split('=')[1]
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatures.split('=')[1])
)
}

Idempotency

HeaderValueTTL
Idempotency-KeyUUIDv424 hours

Return cached response (same status, same body) if same key seen within TTL. Return 409 Conflict if different request body arrives with same key.

API Security Checklist

  • [ ] HTTPS enforced (HTTP → 301 redirect)
  • [ ] TLS 1.2+ only (no TLS 1.0/1.1)
  • [ ] CORS whitelist per environment, never * with credentials
  • [ ] Input validation at boundary (Zod, Joi, Pydantic)
  • [ ] Parameterized queries (no SQL injection). Never string interpolation.
  • [ ] No secrets in responses, logs, or error messages
  • [ ] Rate limiting on auth + password endpoints
  • [ ] Request size limit: 1MB default, configurable per endpoint
  • [ ] Body parsing limits (depth, field count, string length)
  • [ ] Security headers: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy

OpenAPI 3.1 Generation

Every endpoint needs:

  • summary: one sentence. Verb + resource.
  • parameters: name, in, required, schema, description, example
  • responses: every possible status code
  • requestBody (for POST/PUT/PATCH): content, schema, required

GraphQL

Schema design
  • Queries for read, Mutations for write, Subscriptions for real-time
  • Max 3 nesting levels per query
  • @deprecated(reason: "Use fieldX instead") for removals
  • DataLoader for N+1 prevention
  • Complexity limits: max depth 5, max cost 1000
Error handling
json
{
"errors": [
{
"message": "Validation error",
"extensions": {
"code": "VALIDATION_ERROR",
"field": "email",
"request_id": "req_abc123"
}
}
]
}

Anti-Patterns

Anti-patternFix
Verbs in URL (/getUsers)Use HTTP methods on noun resources
Page-based pagination for real-time dataCursor-based with opaque cursors
No rate limit headersInclude X-RateLimit-* on every response
Returning 500 with stack traceLog internally, return generic message
Breaking changes without migrationVersion via URL, deprecation + sunset headers
No idempotency on POST createsAdd Idempotency-Key header support
Inconsistent error format across endpointsStandard envelope for all errors
GraphQL without complexity limitsImplement query depth + cost analysis
Nested resources > 2 levelsRestructure. Deep nesting = tight coupling.
POST for everythingUse correct HTTP methods. GET=read, PUT=replace, PATCH=partial.

Production Checklist

  • [ ] All endpoints documented with OpenAPI 3.1
  • [ ] Envelope: { data, meta, error, request_id } on every response
  • [ ] Cursor-based pagination for public endpoints
  • [ ] Rate limit headers on every response
  • [ ] Rate limiting on auth endpoints (5/15min login, 3/60min reset)
  • [ ] Idempotency-Key support on POST/PATCH
  • [ ] Webhook signature verification (HMAC-SHA256)
  • [ ] Security headers on every response
  • [ ] CORS whitelist (never * with credentials)
  • [ ] Input validation at boundary
  • [ ] Parameterized queries everywhere
  • [ ] Error responses include request_id and code
  • [ ] Versioning strategy defined (URL path preferred)
  • [ ] Deprecation + Sunset headers on deprecated endpoints

Sources

  • Stripe API Reference — idempotency, pagination, webhooks, error format
  • GitHub REST API — resource naming, versioning
  • Twilio API — webhook signature verification
  • OpenAPI 3.1 Specification (openapis.org)
  • JSON:API Specification (jsonapi.org)
  • GraphQL Relay Connection Specification
  • IETF RFC 7231 — HTTP semantics
  • IETF RFC 6585 — Additional HTTP status codes
  • Slack API — rate limiting headers

Checklist

  • [ ] Skill loads without errors in the AI agent
  • [ ] YAML frontmatter is valid (description, compatibility, audience)
  • [ ] Workflow section provides clear step-by-step instructions
  • [ ] Error handling section covers common failure modes
  • [ ] All referenced files (references/, scripts/, assets/) exist
  • [ ] Skill triggers correctly for intended use cases
  • [ ] No broken links or missing resources

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
93
Repository forks
10
7-day trend score
23

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/eliasoulkadi/shokunin/api-forge/badge)](https://verified-skill.com/skills/eliasoulkadi/shokunin/api-forge)

Something wrong with this skill or its page? Tell us.