{
  "schemaVersion": "1.0",
  "item": {
    "slug": "afrexai-api-architect",
    "name": "API Architect",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/1kalin/afrexai-api-architect",
    "canonicalUrl": "https://clawhub.ai/1kalin/afrexai-api-architect",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/afrexai-api-architect",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-api-architect",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "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."
        },
        {
          "label": "Upgrade existing",
          "body": "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."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/afrexai-api-architect"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/afrexai-api-architect",
    "agentPageUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent",
    "manifestUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "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."
      },
      {
        "label": "Upgrade existing",
        "body": "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."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "API Architect — Full Lifecycle API Development",
        "body": "Design, build, test, document, secure, and monitor production-grade APIs. Not just curl commands — a complete engineering methodology."
      },
      {
        "title": "When to Use",
        "body": "Designing a new API (REST, GraphQL, or gRPC)\nReviewing an existing API for quality, consistency, or security\nGenerating or validating OpenAPI/Swagger specs\nBuilding comprehensive test suites (unit, integration, contract, load)\nDebugging production API issues\nPlanning API versioning and deprecation\nSetting up monitoring, rate limiting, and error handling"
      },
      {
        "title": "Design-First Approach",
        "body": "Always design before coding. The spec IS the contract.\n\nResource Modeling\n\nMap your domain to resources using this template:\n\n# api-design.yaml\nservice: order-management\nbase_path: /api/v1\nresources:\n  - name: orders\n    path: /orders\n    description: Customer purchase orders\n    identifier: order_id (UUID)\n    parent: null\n    operations: [list, create, get, update, cancel]\n    sub_resources:\n      - name: line_items\n        path: /orders/{order_id}/items\n        operations: [list, add, update, remove]\n      - name: payments\n        path: /orders/{order_id}/payments\n        operations: [list, create, get, refund]\n    states: [draft, confirmed, processing, shipped, delivered, cancelled]\n    transitions:\n      - from: draft → to: confirmed (action: confirm)\n      - from: confirmed → to: processing (action: process)\n      - from: processing → to: shipped (action: ship)\n      - from: shipped → to: delivered (action: deliver)\n      - from: [draft, confirmed] → to: cancelled (action: cancel)\n\nNaming Conventions Checklist\n\nRuleGoodBadPlural 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}\n\nHTTP Methods — Decision Matrix\n\nNeed to...                          → Method   Idempotent?  Safe?\nGet a resource or collection        → GET      Yes          Yes\nCreate a new resource               → POST     No           No\nFull replace of a resource          → PUT      Yes          No\nPartial update of a resource        → PATCH    No*          No\nRemove a resource                   → DELETE   Yes          No\nCheck if resource exists            → HEAD     Yes          Yes\nList allowed methods                → OPTIONS  Yes          Yes\n\n* PATCH can be idempotent if using JSON Merge Patch\n\nStatus Code Decision Tree\n\nSuccess?\n├── Created something new? → 201 Created (Location header)\n├── Accepted for async processing? → 202 Accepted (include status URL)\n├── No body to return? → 204 No Content\n└── Returning data? → 200 OK\n\nClient error?\n├── Malformed request syntax? → 400 Bad Request\n├── No/invalid credentials? → 401 Unauthorized\n├── Valid credentials but insufficient permissions? → 403 Forbidden\n├── Resource doesn't exist? → 404 Not Found\n├── Method not allowed on resource? → 405 Method Not Allowed\n├── Conflict with current state? → 409 Conflict\n├── Resource permanently gone? → 410 Gone\n├── Validation failed? → 422 Unprocessable Entity\n├── Too many requests? → 429 Too Many Requests (Retry-After header)\n└── Precondition failed (etag mismatch)? → 412 Precondition Failed\n\nServer error?\n├── Unexpected failure? → 500 Internal Server Error\n├── Upstream dependency failed? → 502 Bad Gateway\n├── Temporarily overloaded? → 503 Service Unavailable (Retry-After)\n└── Upstream timeout? → 504 Gateway Timeout"
      },
      {
        "title": "Request/Response Design",
        "body": "Standard Response Envelope\n\n// Success (single resource)\n{\n  \"data\": { \"id\": \"ord_abc123\", \"status\": \"confirmed\", ... },\n  \"meta\": { \"request_id\": \"req_xyz789\" }\n}\n\n// Success (collection)\n{\n  \"data\": [ ... ],\n  \"meta\": { \"request_id\": \"req_xyz789\" },\n  \"pagination\": {\n    \"total\": 142,\n    \"page\": 2,\n    \"per_page\": 20,\n    \"total_pages\": 8,\n    \"next\": \"/api/v1/orders?page=3&per_page=20\",\n    \"prev\": \"/api/v1/orders?page=1&per_page=20\"\n  }\n}\n\n// Error\n{\n  \"error\": {\n    \"code\": \"VALIDATION_FAILED\",\n    \"message\": \"Request validation failed\",\n    \"details\": [\n      { \"field\": \"email\", \"message\": \"Must be a valid email address\", \"code\": \"INVALID_FORMAT\" },\n      { \"field\": \"age\", \"message\": \"Must be at least 18\", \"code\": \"MIN_VALUE\", \"min\": 18 }\n    ]\n  },\n  \"meta\": { \"request_id\": \"req_xyz789\" }\n}\n\nPagination Patterns — When to Use Which\n\nPatternUse 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\n\nFiltering, Sorting, Field Selection\n\n# Filtering\nGET /orders?status=active&created_after=2024-01-01&total_min=100\n\n# Sorting (prefix - for descending)\nGET /orders?sort=-created_at,total\n\n# Field selection (reduce payload)\nGET /orders?fields=id,status,total,customer.name\n\n# Search\nGET /products?q=wireless+headphones\n\n# Combined\nGET /orders?status=active&sort=-created_at&fields=id,status,total&page=1&per_page=10"
      },
      {
        "title": "Generate OpenAPI 3.1 Spec",
        "body": "For each resource in your design, generate a complete spec:\n\nopenapi: 3.1.0\ninfo:\n  title: Order Management API\n  version: 1.0.0\n  description: |\n    Order lifecycle management.\n    \n    ## Authentication\n    All endpoints require Bearer token authentication.\n    \n    ## Rate Limits\n    - Standard: 100 req/min\n    - Bulk operations: 10 req/min\n  contact:\n    name: API Support\n    email: api@example.com\n  license:\n    name: MIT\nservers:\n  - url: https://api.example.com/v1\n    description: Production\n  - url: https://staging-api.example.com/v1\n    description: Staging\n\npaths:\n  /orders:\n    get:\n      operationId: listOrders\n      summary: List orders\n      tags: [Orders]\n      parameters:\n        - $ref: '#/components/parameters/PageParam'\n        - $ref: '#/components/parameters/PerPageParam'\n        - name: status\n          in: query\n          schema:\n            $ref: '#/components/schemas/OrderStatus'\n        - name: created_after\n          in: query\n          schema:\n            type: string\n            format: date-time\n      responses:\n        '200':\n          description: Order list\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrderListResponse'\n        '401':\n          $ref: '#/components/responses/Unauthorized'\n\n    post:\n      operationId: createOrder\n      summary: Create an order\n      tags: [Orders]\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOrderRequest'\n            examples:\n              basic:\n                summary: Basic order\n                value:\n                  customer_id: \"cust_abc\"\n                  items:\n                    - product_id: \"prod_xyz\"\n                      quantity: 2\n      responses:\n        '201':\n          description: Order created\n          headers:\n            Location:\n              schema:\n                type: string\n              description: URL of created order\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrderResponse'\n        '422':\n          $ref: '#/components/responses/ValidationError'\n\ncomponents:\n  securitySchemes:\n    BearerAuth:\n      type: http\n      scheme: bearer\n      bearerFormat: JWT\n\n  parameters:\n    PageParam:\n      name: page\n      in: query\n      schema: { type: integer, minimum: 1, default: 1 }\n    PerPageParam:\n      name: per_page\n      in: query\n      schema: { type: integer, minimum: 1, maximum: 100, default: 20 }\n\n  responses:\n    Unauthorized:\n      description: Missing or invalid authentication\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/ErrorResponse'\n    ValidationError:\n      description: Request validation failed\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/ErrorResponse'\n\nsecurity:\n  - BearerAuth: []"
      },
      {
        "title": "Spec Quality Checklist (score each 0-2)",
        "body": "#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\n\nScore: ___/20 (Target: 16+)"
      },
      {
        "title": "Request Validation Layer",
        "body": "Every endpoint MUST validate before processing:\n\nValidation Order:\n1. Content-Type header (reject non-JSON early)\n2. Authentication (401 before wasting cycles)\n3. Authorization (403 - does this user have access?)\n4. Path parameters (404 - does the resource exist?)\n5. Query parameters (400 - valid types/ranges?)\n6. Request body schema (422 - valid structure?)\n7. Business rules (422 - valid state transition?)"
      },
      {
        "title": "Error Handling — Standard Error Codes",
        "body": "Define a consistent error code enum for your API:\n\n# Authentication & Authorization\nAUTH_REQUIRED          — No credentials provided\nAUTH_INVALID           — Invalid/expired credentials\nAUTH_INSUFFICIENT      — Valid credentials, wrong permissions\nAUTH_RATE_LIMITED       — Too many auth attempts\n\n# Validation\nVALIDATION_FAILED      — Generic validation error (see details array)\nINVALID_FORMAT         — Field format wrong (email, UUID, etc.)\nREQUIRED_FIELD         — Required field missing\nOUT_OF_RANGE           — Value outside allowed range\nINVALID_ENUM           — Value not in allowed set\n\n# Resource\nNOT_FOUND              — Resource doesn't exist\nALREADY_EXISTS         — Duplicate (unique constraint)\nCONFLICT               — State conflict (e.g., already cancelled)\nGONE                   — Resource permanently deleted\n\n# Business Logic\nINSUFFICIENT_FUNDS     — Payment-related\nQUOTA_EXCEEDED         — Usage limit reached\nFEATURE_DISABLED       — Feature flag off\nDEPENDENCY_FAILED      — Upstream service error\n\n# System\nINTERNAL_ERROR         — Unexpected server error\nSERVICE_UNAVAILABLE    — Temporarily down\nTIMEOUT                — Request took too long"
      },
      {
        "title": "Idempotency",
        "body": "For non-idempotent operations (POST), require an idempotency key:\n\nRequest:\nPOST /orders\nIdempotency-Key: ord_req_abc123\n\nServer behavior:\n1. Check if Idempotency-Key was seen before\n2. If yes → return cached response (same status, same body)\n3. If no → process request, cache response for 24h\n4. Key format: client-generated UUID or meaningful string"
      },
      {
        "title": "Rate Limiting",
        "body": "Standard headers to include:\n\nX-RateLimit-Limit: 100          # Max requests per window\nX-RateLimit-Remaining: 67       # Remaining in current window\nX-RateLimit-Reset: 1706886400   # Unix timestamp when window resets\nRetry-After: 30                 # Seconds to wait (on 429)\n\nRate limit tiers:\n\nTierLimitWindowUse CaseStandard100/minSlidingNormal API callsBulk10/minSlidingBatch operationsSearch30/minSlidingFull-text searchAuth5/minFixedLogin attemptsWebhook1000/minSlidingIncoming webhooks"
      },
      {
        "title": "Test Pyramid for APIs",
        "body": "/  E2E  \\          — 5-10 critical user flows\n       / Contract \\        — Schema validation, backward compat\n      / Integration \\      — Database, external services, auth\n     /    Unit Tests  \\    — Business logic, validation, transforms\n    ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾"
      },
      {
        "title": "Test Checklist Per Endpoint",
        "body": "For EVERY endpoint, test these scenarios:\n\nendpoint: POST /orders\ntests:\n  happy_path:\n    - Creates order with valid data → 201\n    - Returns created resource with ID\n    - Location header points to new resource\n    - Timestamps are set (created_at, updated_at)\n  \n  validation:\n    - Missing required fields → 422 with field-level errors\n    - Invalid field types (string where int expected) → 422\n    - Empty body → 400\n    - Invalid Content-Type → 415\n    - Extra unknown fields → ignored or 422 (pick one, be consistent)\n    - Boundary values (min/max length, 0, negative, empty string vs null)\n  \n  authentication:\n    - No token → 401\n    - Expired token → 401\n    - Invalid token → 401\n    - Valid token, wrong scope → 403\n  \n  authorization:\n    - User accessing own resource → 200\n    - User accessing other's resource → 403 or 404 (security choice)\n    - Admin accessing any resource → 200\n  \n  edge_cases:\n    - Duplicate creation (same idempotency key) → same 201 response\n    - Concurrent creation race condition → one wins, one gets 409\n    - Resource at max relationships → 422\n    - Unicode in text fields → handled correctly\n    - Very long strings → 422 with max length error\n    - SQL injection in params → no effect (parameterized queries)\n    - XSS in text fields → stored safely, escaped on output\n  \n  performance:\n    - Response time < 200ms (p95)\n    - List endpoint with 10K records → paginated, < 500ms\n    - Bulk operation timeout handling"
      },
      {
        "title": "curl Testing Recipes",
        "body": "# === Setup ===\nBASE=\"https://api.example.com/v1\"\nTOKEN=\"your_bearer_token\"\nalias api='curl -s -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\"'\n\n# === CRUD Lifecycle Test ===\n# Create\nORDER=$(api -X POST \"$BASE/orders\" -d '{\"customer_id\":\"cust_1\",\"items\":[{\"product_id\":\"prod_1\",\"qty\":2}]}')\nORDER_ID=$(echo \"$ORDER\" | jq -r '.data.id')\necho \"Created: $ORDER_ID\"\n\n# Read\napi \"$BASE/orders/$ORDER_ID\" | jq .\n\n# Update\napi -X PATCH \"$BASE/orders/$ORDER_ID\" -d '{\"notes\":\"Rush order\"}' | jq .\n\n# List with filters\napi \"$BASE/orders?status=draft&sort=-created_at&per_page=5\" | jq .\n\n# Action (state transition)\napi -X POST \"$BASE/orders/$ORDER_ID/confirm\" | jq .\n\n# Delete\ncurl -s -o /dev/null -w \"%{http_code}\" -X DELETE -H \"Authorization: Bearer $TOKEN\" \"$BASE/orders/$ORDER_ID\"\n\n# === Error Testing ===\n# No auth\ncurl -s \"$BASE/orders\" | jq .error\n\n# Invalid body\napi -X POST \"$BASE/orders\" -d '{\"invalid\": true}' | jq .error\n\n# Not found\napi \"$BASE/orders/nonexistent\" | jq .error\n\n# === Performance ===\n# Timing breakdown\ncurl -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\"\n\n# Quick load test (50 requests, 10 concurrent)\nseq 50 | xargs -P10 -I{} curl -s -o /dev/null -w \"%{http_code} %{time_total}s\\n\" -H \"Authorization: Bearer $TOKEN\" \"$BASE/orders\""
      },
      {
        "title": "Contract Testing",
        "body": "Validate your API hasn't broken backward compatibility:\n\n# contract-tests.yaml\ncontract:\n  name: Order API Contract\n  version: 1.0.0\n  \n  rules:\n    # These changes are SAFE (non-breaking)\n    safe:\n      - Adding new optional fields to responses\n      - Adding new endpoints\n      - Adding new optional query parameters\n      - Adding new enum values (if clients handle unknown)\n      - Widening a constraint (min: 5 → min: 1)\n    \n    # These changes are BREAKING\n    breaking:\n      - Removing a response field\n      - Renaming a response field\n      - Changing a field type\n      - Adding a new required request field\n      - Removing an endpoint\n      - Narrowing a constraint (max: 100 → max: 50)\n      - Changing error response format\n      - Removing an enum value\n    \n    # Verify after every change\n    checks:\n      - All existing fields still present in responses\n      - All existing field types unchanged\n      - All existing required fields still required (no more, no fewer)\n      - Default values unchanged\n      - Error format unchanged"
      },
      {
        "title": "Security Checklist (audit every API)",
        "body": "authentication:\n  - [ ] All endpoints require auth (except /health, /docs, public webhooks)\n  - [ ] Tokens expire (short-lived access + long-lived refresh)\n  - [ ] Token rotation supported\n  - [ ] Failed auth returns 401 with no info leakage\n  - [ ] API keys are hashed in storage (never plain text)\n\nauthorization:\n  - [ ] Resource-level checks (user can only access their data)\n  - [ ] Endpoint-level checks (role-based access)\n  - [ ] No IDOR vulnerabilities (can't guess other users' resource IDs)\n  - [ ] Admin endpoints separately protected\n  - [ ] Webhook endpoints verify signatures\n\ninput_validation:\n  - [ ] All inputs validated server-side (never trust client)\n  - [ ] SQL injection prevented (parameterized queries only)\n  - [ ] NoSQL injection prevented\n  - [ ] Path traversal prevented\n  - [ ] Request size limited (body, headers, URL length)\n  - [ ] File upload types restricted and scanned\n\noutput_security:\n  - [ ] No sensitive data in responses (passwords, tokens, internal IDs)\n  - [ ] No stack traces in production errors\n  - [ ] Consistent error format (no info leakage in different error types)\n  - [ ] PII redacted in logs\n\ntransport:\n  - [ ] HTTPS only (HTTP redirects to HTTPS)\n  - [ ] HSTS header set\n  - [ ] TLS 1.2+ required\n  - [ ] CORS configured restrictively (specific origins, not *)\n  \nheaders:\n  - [ ] X-Content-Type-Options: nosniff\n  - [ ] X-Frame-Options: DENY\n  - [ ] Content-Security-Policy set\n  - [ ] No Server version header\n  - [ ] Cache-Control: no-store for sensitive endpoints"
      },
      {
        "title": "CORS Configuration",
        "body": "# Restrictive (recommended)\ncors:\n  origins:\n    - https://app.example.com\n    - https://admin.example.com\n  methods: [GET, POST, PUT, PATCH, DELETE]\n  headers: [Authorization, Content-Type, X-Request-ID]\n  credentials: true\n  max_age: 3600\n\n# Common mistakes to avoid:\n# ❌ Access-Control-Allow-Origin: *  (with credentials)\n# ❌ Reflecting Origin header without validation\n# ❌ Allowing all methods/headers"
      },
      {
        "title": "Versioning Strategy Decision",
        "body": "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\n\nRecommended: URL path for major versions, header for minor variations."
      },
      {
        "title": "Deprecation Playbook",
        "body": "Timeline:\n1. T+0: Announce deprecation (docs, changelog, email)\n2. T+0: Add Deprecation + Sunset headers to old endpoints\n3. T+30d: Log warnings for old endpoint usage\n4. T+60d: Email heavy users of old endpoint directly\n5. T+90d: Return 299 warning header\n6. T+180d: Shut down old endpoint (410 Gone)\n\nHeaders:\nDeprecation: true\nSunset: Sat, 01 Jun 2025 00:00:00 GMT\nLink: <https://api.example.com/v2/orders>; rel=\"successor-version\""
      },
      {
        "title": "Migration Guide Template",
        "body": "# Migrating from v1 to v2\n\n## Breaking Changes\n1. `user.name` split into `user.first_name` + `user.last_name`\n2. Pagination changed from offset to cursor-based\n3. Error format updated (see new schema)\n\n## Step-by-Step Migration\n1. Update your client SDK to v2 (`npm install @example/sdk@2`)\n2. Update response parsing for split name fields\n3. Replace `?page=N` with `?after=cursor` pagination\n4. Update error handling for new error format\n\n## Compatibility Mode\nSet `X-Compat-Mode: v1` header to get v1-style responses from v2 endpoints.\nAvailable until 2025-06-01."
      },
      {
        "title": "Key Metrics Dashboard",
        "body": "availability:\n  - Uptime percentage (target: 99.9% = 8.7h downtime/year)\n  - Health check status (/health endpoint)\n  - Error rate (5xx / total requests)\n\nperformance:\n  - p50 latency (target: < 100ms)\n  - p95 latency (target: < 500ms)\n  - p99 latency (target: < 1000ms)\n  - Throughput (requests/second)\n  - Time to first byte (TTFB)\n\nbusiness:\n  - Requests per endpoint (usage patterns)\n  - Unique API consumers/day\n  - Error rate by endpoint\n  - Rate limit hits/day\n  - Authentication failures/day\n\ninfrastructure:\n  - Database query time (p95)\n  - Connection pool utilization\n  - Memory/CPU per instance\n  - Queue depth (async operations)"
      },
      {
        "title": "Structured Logging",
        "body": "Every request should log:\n\n{\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"level\": \"info\",\n  \"request_id\": \"req_abc123\",\n  \"method\": \"POST\",\n  \"path\": \"/api/v1/orders\",\n  \"status\": 201,\n  \"duration_ms\": 45,\n  \"user_id\": \"usr_xyz\",\n  \"ip\": \"203.0.113.1\",\n  \"user_agent\": \"MyApp/2.0\",\n  \"request_size\": 256,\n  \"response_size\": 1024\n}"
      },
      {
        "title": "Health Check Endpoint",
        "body": "// GET /health — for load balancers (simple)\n{ \"status\": \"ok\" }\n\n// GET /health/detailed — for monitoring (authenticated)\n{\n  \"status\": \"degraded\",\n  \"version\": \"1.5.2\",\n  \"uptime_seconds\": 86400,\n  \"checks\": {\n    \"database\": { \"status\": \"ok\", \"latency_ms\": 5 },\n    \"redis\": { \"status\": \"ok\", \"latency_ms\": 2 },\n    \"external_payment_api\": { \"status\": \"degraded\", \"latency_ms\": 2500, \"error\": \"timeout\" },\n    \"disk\": { \"status\": \"ok\", \"free_gb\": 45.2 }\n  }\n}"
      },
      {
        "title": "Phase 8: API Review Scoring",
        "body": "When reviewing an existing API, score across these dimensions:"
      },
      {
        "title": "API Quality Rubric (0-100)",
        "body": "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\n\nScore: ___/100\n\nRatingScoreAction🟢 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"
      },
      {
        "title": "Review Output Template",
        "body": "## API Review: [Service Name]\n\n**Date:** YYYY-MM-DD\n**Reviewer:** [Agent]\n**Score:** XX/100 (Rating)\n\n### Summary\n[2-3 sentence overview of API quality]\n\n### Scores by Dimension\n- Design Consistency: X/20 — [key finding]\n- Documentation: X/15 — [key finding]\n- Error Handling: X/15 — [key finding]\n- Security: X/20 — [key finding]\n- Performance: X/15 — [key finding]\n- Developer Experience: X/15 — [key finding]\n\n### Critical Issues (fix immediately)\n1. [Issue + recommendation]\n\n### High Priority (fix this sprint)\n1. [Issue + recommendation]\n\n### Nice to Have (backlog)\n1. [Issue + recommendation]\n\n### Positive Highlights\n- [What's working well]"
      },
      {
        "title": "Schema Design Principles",
        "body": "# Good: clear types, nullable where appropriate, connections for lists\ntype Order {\n  id: ID!\n  status: OrderStatus!\n  customer: Customer!\n  items(first: Int, after: String): ItemConnection!\n  total: Money!\n  createdAt: DateTime!\n  updatedAt: DateTime!\n}\n\ntype Money {\n  amount: Int!       # cents, not dollars (avoid float)\n  currency: Currency!\n}\n\nenum OrderStatus {\n  DRAFT\n  CONFIRMED\n  PROCESSING\n  SHIPPED\n  DELIVERED\n  CANCELLED\n}\n\n# Mutations return the modified resource + errors\ntype CreateOrderPayload {\n  order: Order\n  errors: [UserError!]!\n}\n\ntype UserError {\n  field: [String!]\n  message: String!\n  code: ErrorCode!\n}"
      },
      {
        "title": "GraphQL Anti-Patterns",
        "body": "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"
      },
      {
        "title": "Timezone Handling",
        "body": "Always store and return UTC (ISO 8601: 2024-01-15T10:30:00Z)\nAccept timezone in input, convert to UTC immediately\nNever use local server time"
      },
      {
        "title": "Large Payloads",
        "body": "Set Content-Length limits (e.g., 1MB default, 10MB for uploads)\nUse streaming for file uploads (multipart/form-data)\nCompress responses (Accept-Encoding: gzip)\nFor very large exports → return 202 + poll status endpoint"
      },
      {
        "title": "Eventual Consistency",
        "body": "If using async processing, always return 202 + status URL\nInclude estimated completion time when possible\nClient should poll with exponential backoff"
      },
      {
        "title": "Concurrent Updates",
        "body": "Use ETags for optimistic concurrency:\n\nGET returns ETag: \"v1\" header\nPUT/PATCH sends If-Match: \"v1\" header\nServer returns 412 if resource changed since"
      },
      {
        "title": "Webhook Design",
        "body": "Include event type, timestamp, and full resource in payload\nSign payloads (HMAC-SHA256)\nExpect retries (make handlers idempotent)\nReturn 200 quickly, process async\nInclude webhook ID for deduplication"
      },
      {
        "title": "Quick Commands",
        "body": "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"
      }
    ],
    "body": "API Architect — Full Lifecycle API Development\n\nDesign, build, test, document, secure, and monitor production-grade APIs. Not just curl commands — a complete engineering methodology.\n\nWhen to Use\nDesigning a new API (REST, GraphQL, or gRPC)\nReviewing an existing API for quality, consistency, or security\nGenerating or validating OpenAPI/Swagger specs\nBuilding comprehensive test suites (unit, integration, contract, load)\nDebugging production API issues\nPlanning API versioning and deprecation\nSetting up monitoring, rate limiting, and error handling\nPhase 1: API Design\nDesign-First Approach\n\nAlways design before coding. The spec IS the contract.\n\nResource Modeling\n\nMap your domain to resources using this template:\n\n# api-design.yaml\nservice: order-management\nbase_path: /api/v1\nresources:\n  - name: orders\n    path: /orders\n    description: Customer purchase orders\n    identifier: order_id (UUID)\n    parent: null\n    operations: [list, create, get, update, cancel]\n    sub_resources:\n      - name: line_items\n        path: /orders/{order_id}/items\n        operations: [list, add, update, remove]\n      - name: payments\n        path: /orders/{order_id}/payments\n        operations: [list, create, get, refund]\n    states: [draft, confirmed, processing, shipped, delivered, cancelled]\n    transitions:\n      - from: draft → to: confirmed (action: confirm)\n      - from: confirmed → to: processing (action: process)\n      - from: processing → to: shipped (action: ship)\n      - from: shipped → to: delivered (action: deliver)\n      - from: [draft, confirmed] → to: cancelled (action: cancel)\n\nNaming Conventions Checklist\nRule\tGood\tBad\nPlural nouns for collections\t/users\t/user, /getUsers\nKebab-case for multi-word\t/line-items\t/lineItems, /line_items\nNo verbs in URLs\tPOST /orders\t/createOrder\nNest for ownership\t/users/123/orders\t/orders?user=123 (for primary relationship)\nMax 3 levels deep\t/users/123/orders\t/users/123/orders/456/items/789/options\nFilter via query params\t/orders?status=active\t/active-orders\nActions as sub-resource\tPOST /orders/123/cancel\tPATCH /orders/123 {cancelled:true}\nHTTP Methods — Decision Matrix\nNeed to...                          → Method   Idempotent?  Safe?\nGet a resource or collection        → GET      Yes          Yes\nCreate a new resource               → POST     No           No\nFull replace of a resource          → PUT      Yes          No\nPartial update of a resource        → PATCH    No*          No\nRemove a resource                   → DELETE   Yes          No\nCheck if resource exists            → HEAD     Yes          Yes\nList allowed methods                → OPTIONS  Yes          Yes\n\n* PATCH can be idempotent if using JSON Merge Patch\n\nStatus Code Decision Tree\nSuccess?\n├── Created something new? → 201 Created (Location header)\n├── Accepted for async processing? → 202 Accepted (include status URL)\n├── No body to return? → 204 No Content\n└── Returning data? → 200 OK\n\nClient error?\n├── Malformed request syntax? → 400 Bad Request\n├── No/invalid credentials? → 401 Unauthorized\n├── Valid credentials but insufficient permissions? → 403 Forbidden\n├── Resource doesn't exist? → 404 Not Found\n├── Method not allowed on resource? → 405 Method Not Allowed\n├── Conflict with current state? → 409 Conflict\n├── Resource permanently gone? → 410 Gone\n├── Validation failed? → 422 Unprocessable Entity\n├── Too many requests? → 429 Too Many Requests (Retry-After header)\n└── Precondition failed (etag mismatch)? → 412 Precondition Failed\n\nServer error?\n├── Unexpected failure? → 500 Internal Server Error\n├── Upstream dependency failed? → 502 Bad Gateway\n├── Temporarily overloaded? → 503 Service Unavailable (Retry-After)\n└── Upstream timeout? → 504 Gateway Timeout\n\nRequest/Response Design\nStandard Response Envelope\n// Success (single resource)\n{\n  \"data\": { \"id\": \"ord_abc123\", \"status\": \"confirmed\", ... },\n  \"meta\": { \"request_id\": \"req_xyz789\" }\n}\n\n// Success (collection)\n{\n  \"data\": [ ... ],\n  \"meta\": { \"request_id\": \"req_xyz789\" },\n  \"pagination\": {\n    \"total\": 142,\n    \"page\": 2,\n    \"per_page\": 20,\n    \"total_pages\": 8,\n    \"next\": \"/api/v1/orders?page=3&per_page=20\",\n    \"prev\": \"/api/v1/orders?page=1&per_page=20\"\n  }\n}\n\n// Error\n{\n  \"error\": {\n    \"code\": \"VALIDATION_FAILED\",\n    \"message\": \"Request validation failed\",\n    \"details\": [\n      { \"field\": \"email\", \"message\": \"Must be a valid email address\", \"code\": \"INVALID_FORMAT\" },\n      { \"field\": \"age\", \"message\": \"Must be at least 18\", \"code\": \"MIN_VALUE\", \"min\": 18 }\n    ]\n  },\n  \"meta\": { \"request_id\": \"req_xyz789\" }\n}\n\nPagination Patterns — When to Use Which\nPattern\tUse When\tPros\tCons\nOffset ?page=2&per_page=20\tSimple UI pagination, small datasets\tEasy to implement, page jumping\tDrift on inserts, slow on large offsets\nCursor ?after=eyJ...&limit=20\tInfinite scroll, real-time feeds, large datasets\tConsistent, performant\tNo page jumping, opaque cursors\nKeyset ?created_after=2024-01-01&limit=20\tTime-series data, logs\tFast, transparent\tRequires sortable field, no count\nFiltering, Sorting, Field Selection\n# Filtering\nGET /orders?status=active&created_after=2024-01-01&total_min=100\n\n# Sorting (prefix - for descending)\nGET /orders?sort=-created_at,total\n\n# Field selection (reduce payload)\nGET /orders?fields=id,status,total,customer.name\n\n# Search\nGET /products?q=wireless+headphones\n\n# Combined\nGET /orders?status=active&sort=-created_at&fields=id,status,total&page=1&per_page=10\n\nPhase 2: OpenAPI Specification\nGenerate OpenAPI 3.1 Spec\n\nFor each resource in your design, generate a complete spec:\n\nopenapi: 3.1.0\ninfo:\n  title: Order Management API\n  version: 1.0.0\n  description: |\n    Order lifecycle management.\n    \n    ## Authentication\n    All endpoints require Bearer token authentication.\n    \n    ## Rate Limits\n    - Standard: 100 req/min\n    - Bulk operations: 10 req/min\n  contact:\n    name: API Support\n    email: api@example.com\n  license:\n    name: MIT\nservers:\n  - url: https://api.example.com/v1\n    description: Production\n  - url: https://staging-api.example.com/v1\n    description: Staging\n\npaths:\n  /orders:\n    get:\n      operationId: listOrders\n      summary: List orders\n      tags: [Orders]\n      parameters:\n        - $ref: '#/components/parameters/PageParam'\n        - $ref: '#/components/parameters/PerPageParam'\n        - name: status\n          in: query\n          schema:\n            $ref: '#/components/schemas/OrderStatus'\n        - name: created_after\n          in: query\n          schema:\n            type: string\n            format: date-time\n      responses:\n        '200':\n          description: Order list\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrderListResponse'\n        '401':\n          $ref: '#/components/responses/Unauthorized'\n\n    post:\n      operationId: createOrder\n      summary: Create an order\n      tags: [Orders]\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOrderRequest'\n            examples:\n              basic:\n                summary: Basic order\n                value:\n                  customer_id: \"cust_abc\"\n                  items:\n                    - product_id: \"prod_xyz\"\n                      quantity: 2\n      responses:\n        '201':\n          description: Order created\n          headers:\n            Location:\n              schema:\n                type: string\n              description: URL of created order\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrderResponse'\n        '422':\n          $ref: '#/components/responses/ValidationError'\n\ncomponents:\n  securitySchemes:\n    BearerAuth:\n      type: http\n      scheme: bearer\n      bearerFormat: JWT\n\n  parameters:\n    PageParam:\n      name: page\n      in: query\n      schema: { type: integer, minimum: 1, default: 1 }\n    PerPageParam:\n      name: per_page\n      in: query\n      schema: { type: integer, minimum: 1, maximum: 100, default: 20 }\n\n  responses:\n    Unauthorized:\n      description: Missing or invalid authentication\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/ErrorResponse'\n    ValidationError:\n      description: Request validation failed\n      content:\n        application/json:\n          schema:\n            $ref: '#/components/schemas/ErrorResponse'\n\nsecurity:\n  - BearerAuth: []\n\nSpec Quality Checklist (score each 0-2)\n#\tCheck\tScore\n1\tEvery endpoint has operationId\t/2\n2\tAll parameters documented with types + constraints\t/2\n3\tRequest bodies have examples\t/2\n4\tAll error responses documented (400, 401, 403, 404, 422, 429, 500)\t/2\n5\tShared schemas use $ref (DRY)\t/2\n6\tPagination parameters standardized\t/2\n7\tSecurity scheme defined + applied globally\t/2\n8\tDescription includes auth, rate limits, versioning info\t/2\n9\tResponse headers documented (Location, Retry-After, ETag)\t/2\n10\tEnums used for fixed value sets\t/2\n\nScore: ___/20 (Target: 16+)\n\nPhase 3: Implementation Patterns\nRequest Validation Layer\n\nEvery endpoint MUST validate before processing:\n\nValidation Order:\n1. Content-Type header (reject non-JSON early)\n2. Authentication (401 before wasting cycles)\n3. Authorization (403 - does this user have access?)\n4. Path parameters (404 - does the resource exist?)\n5. Query parameters (400 - valid types/ranges?)\n6. Request body schema (422 - valid structure?)\n7. Business rules (422 - valid state transition?)\n\nError Handling — Standard Error Codes\n\nDefine a consistent error code enum for your API:\n\n# Authentication & Authorization\nAUTH_REQUIRED          — No credentials provided\nAUTH_INVALID           — Invalid/expired credentials\nAUTH_INSUFFICIENT      — Valid credentials, wrong permissions\nAUTH_RATE_LIMITED       — Too many auth attempts\n\n# Validation\nVALIDATION_FAILED      — Generic validation error (see details array)\nINVALID_FORMAT         — Field format wrong (email, UUID, etc.)\nREQUIRED_FIELD         — Required field missing\nOUT_OF_RANGE           — Value outside allowed range\nINVALID_ENUM           — Value not in allowed set\n\n# Resource\nNOT_FOUND              — Resource doesn't exist\nALREADY_EXISTS         — Duplicate (unique constraint)\nCONFLICT               — State conflict (e.g., already cancelled)\nGONE                   — Resource permanently deleted\n\n# Business Logic\nINSUFFICIENT_FUNDS     — Payment-related\nQUOTA_EXCEEDED         — Usage limit reached\nFEATURE_DISABLED       — Feature flag off\nDEPENDENCY_FAILED      — Upstream service error\n\n# System\nINTERNAL_ERROR         — Unexpected server error\nSERVICE_UNAVAILABLE    — Temporarily down\nTIMEOUT                — Request took too long\n\nIdempotency\n\nFor non-idempotent operations (POST), require an idempotency key:\n\nRequest:\nPOST /orders\nIdempotency-Key: ord_req_abc123\n\nServer behavior:\n1. Check if Idempotency-Key was seen before\n2. If yes → return cached response (same status, same body)\n3. If no → process request, cache response for 24h\n4. Key format: client-generated UUID or meaningful string\n\nRate Limiting\n\nStandard headers to include:\n\nX-RateLimit-Limit: 100          # Max requests per window\nX-RateLimit-Remaining: 67       # Remaining in current window\nX-RateLimit-Reset: 1706886400   # Unix timestamp when window resets\nRetry-After: 30                 # Seconds to wait (on 429)\n\n\nRate limit tiers:\n\nTier\tLimit\tWindow\tUse Case\nStandard\t100/min\tSliding\tNormal API calls\nBulk\t10/min\tSliding\tBatch operations\nSearch\t30/min\tSliding\tFull-text search\nAuth\t5/min\tFixed\tLogin attempts\nWebhook\t1000/min\tSliding\tIncoming webhooks\nPhase 4: Testing Strategy\nTest Pyramid for APIs\n        /  E2E  \\          — 5-10 critical user flows\n       / Contract \\        — Schema validation, backward compat\n      / Integration \\      — Database, external services, auth\n     /    Unit Tests  \\    — Business logic, validation, transforms\n    ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\n\nTest Checklist Per Endpoint\n\nFor EVERY endpoint, test these scenarios:\n\nendpoint: POST /orders\ntests:\n  happy_path:\n    - Creates order with valid data → 201\n    - Returns created resource with ID\n    - Location header points to new resource\n    - Timestamps are set (created_at, updated_at)\n  \n  validation:\n    - Missing required fields → 422 with field-level errors\n    - Invalid field types (string where int expected) → 422\n    - Empty body → 400\n    - Invalid Content-Type → 415\n    - Extra unknown fields → ignored or 422 (pick one, be consistent)\n    - Boundary values (min/max length, 0, negative, empty string vs null)\n  \n  authentication:\n    - No token → 401\n    - Expired token → 401\n    - Invalid token → 401\n    - Valid token, wrong scope → 403\n  \n  authorization:\n    - User accessing own resource → 200\n    - User accessing other's resource → 403 or 404 (security choice)\n    - Admin accessing any resource → 200\n  \n  edge_cases:\n    - Duplicate creation (same idempotency key) → same 201 response\n    - Concurrent creation race condition → one wins, one gets 409\n    - Resource at max relationships → 422\n    - Unicode in text fields → handled correctly\n    - Very long strings → 422 with max length error\n    - SQL injection in params → no effect (parameterized queries)\n    - XSS in text fields → stored safely, escaped on output\n  \n  performance:\n    - Response time < 200ms (p95)\n    - List endpoint with 10K records → paginated, < 500ms\n    - Bulk operation timeout handling\n\ncurl Testing Recipes\n# === Setup ===\nBASE=\"https://api.example.com/v1\"\nTOKEN=\"your_bearer_token\"\nalias api='curl -s -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\"'\n\n# === CRUD Lifecycle Test ===\n# Create\nORDER=$(api -X POST \"$BASE/orders\" -d '{\"customer_id\":\"cust_1\",\"items\":[{\"product_id\":\"prod_1\",\"qty\":2}]}')\nORDER_ID=$(echo \"$ORDER\" | jq -r '.data.id')\necho \"Created: $ORDER_ID\"\n\n# Read\napi \"$BASE/orders/$ORDER_ID\" | jq .\n\n# Update\napi -X PATCH \"$BASE/orders/$ORDER_ID\" -d '{\"notes\":\"Rush order\"}' | jq .\n\n# List with filters\napi \"$BASE/orders?status=draft&sort=-created_at&per_page=5\" | jq .\n\n# Action (state transition)\napi -X POST \"$BASE/orders/$ORDER_ID/confirm\" | jq .\n\n# Delete\ncurl -s -o /dev/null -w \"%{http_code}\" -X DELETE -H \"Authorization: Bearer $TOKEN\" \"$BASE/orders/$ORDER_ID\"\n\n# === Error Testing ===\n# No auth\ncurl -s \"$BASE/orders\" | jq .error\n\n# Invalid body\napi -X POST \"$BASE/orders\" -d '{\"invalid\": true}' | jq .error\n\n# Not found\napi \"$BASE/orders/nonexistent\" | jq .error\n\n# === Performance ===\n# Timing breakdown\ncurl -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\"\n\n# Quick load test (50 requests, 10 concurrent)\nseq 50 | xargs -P10 -I{} curl -s -o /dev/null -w \"%{http_code} %{time_total}s\\n\" -H \"Authorization: Bearer $TOKEN\" \"$BASE/orders\"\n\nContract Testing\n\nValidate your API hasn't broken backward compatibility:\n\n# contract-tests.yaml\ncontract:\n  name: Order API Contract\n  version: 1.0.0\n  \n  rules:\n    # These changes are SAFE (non-breaking)\n    safe:\n      - Adding new optional fields to responses\n      - Adding new endpoints\n      - Adding new optional query parameters\n      - Adding new enum values (if clients handle unknown)\n      - Widening a constraint (min: 5 → min: 1)\n    \n    # These changes are BREAKING\n    breaking:\n      - Removing a response field\n      - Renaming a response field\n      - Changing a field type\n      - Adding a new required request field\n      - Removing an endpoint\n      - Narrowing a constraint (max: 100 → max: 50)\n      - Changing error response format\n      - Removing an enum value\n    \n    # Verify after every change\n    checks:\n      - All existing fields still present in responses\n      - All existing field types unchanged\n      - All existing required fields still required (no more, no fewer)\n      - Default values unchanged\n      - Error format unchanged\n\nPhase 5: Security\nSecurity Checklist (audit every API)\nauthentication:\n  - [ ] All endpoints require auth (except /health, /docs, public webhooks)\n  - [ ] Tokens expire (short-lived access + long-lived refresh)\n  - [ ] Token rotation supported\n  - [ ] Failed auth returns 401 with no info leakage\n  - [ ] API keys are hashed in storage (never plain text)\n\nauthorization:\n  - [ ] Resource-level checks (user can only access their data)\n  - [ ] Endpoint-level checks (role-based access)\n  - [ ] No IDOR vulnerabilities (can't guess other users' resource IDs)\n  - [ ] Admin endpoints separately protected\n  - [ ] Webhook endpoints verify signatures\n\ninput_validation:\n  - [ ] All inputs validated server-side (never trust client)\n  - [ ] SQL injection prevented (parameterized queries only)\n  - [ ] NoSQL injection prevented\n  - [ ] Path traversal prevented\n  - [ ] Request size limited (body, headers, URL length)\n  - [ ] File upload types restricted and scanned\n\noutput_security:\n  - [ ] No sensitive data in responses (passwords, tokens, internal IDs)\n  - [ ] No stack traces in production errors\n  - [ ] Consistent error format (no info leakage in different error types)\n  - [ ] PII redacted in logs\n\ntransport:\n  - [ ] HTTPS only (HTTP redirects to HTTPS)\n  - [ ] HSTS header set\n  - [ ] TLS 1.2+ required\n  - [ ] CORS configured restrictively (specific origins, not *)\n  \nheaders:\n  - [ ] X-Content-Type-Options: nosniff\n  - [ ] X-Frame-Options: DENY\n  - [ ] Content-Security-Policy set\n  - [ ] No Server version header\n  - [ ] Cache-Control: no-store for sensitive endpoints\n\nCORS Configuration\n# Restrictive (recommended)\ncors:\n  origins:\n    - https://app.example.com\n    - https://admin.example.com\n  methods: [GET, POST, PUT, PATCH, DELETE]\n  headers: [Authorization, Content-Type, X-Request-ID]\n  credentials: true\n  max_age: 3600\n\n# Common mistakes to avoid:\n# ❌ Access-Control-Allow-Origin: *  (with credentials)\n# ❌ Reflecting Origin header without validation\n# ❌ Allowing all methods/headers\n\nPhase 6: Versioning & Deprecation\nVersioning Strategy Decision\nStrategy\tExample\tPros\tCons\tUse When\nURL path\t/v1/orders\tExplicit, easy routing\tURL pollution\tPublic APIs, multiple major versions\nHeader\tAPI-Version: 2024-01\tClean URLs\tHidden, harder to test\tInternal APIs\nQuery param\t?version=2\tEasy to test\tPollutes params\tQuick prototypes\nDate-based\t2024-01-15\tClear timeline\tMany versions\tStripe-style APIs\n\nRecommended: URL path for major versions, header for minor variations.\n\nDeprecation Playbook\nTimeline:\n1. T+0: Announce deprecation (docs, changelog, email)\n2. T+0: Add Deprecation + Sunset headers to old endpoints\n3. T+30d: Log warnings for old endpoint usage\n4. T+60d: Email heavy users of old endpoint directly\n5. T+90d: Return 299 warning header\n6. T+180d: Shut down old endpoint (410 Gone)\n\nHeaders:\nDeprecation: true\nSunset: Sat, 01 Jun 2025 00:00:00 GMT\nLink: <https://api.example.com/v2/orders>; rel=\"successor-version\"\n\nMigration Guide Template\n# Migrating from v1 to v2\n\n## Breaking Changes\n1. `user.name` split into `user.first_name` + `user.last_name`\n2. Pagination changed from offset to cursor-based\n3. Error format updated (see new schema)\n\n## Step-by-Step Migration\n1. Update your client SDK to v2 (`npm install @example/sdk@2`)\n2. Update response parsing for split name fields\n3. Replace `?page=N` with `?after=cursor` pagination\n4. Update error handling for new error format\n\n## Compatibility Mode\nSet `X-Compat-Mode: v1` header to get v1-style responses from v2 endpoints.\nAvailable until 2025-06-01.\n\nPhase 7: Monitoring & Observability\nKey Metrics Dashboard\navailability:\n  - Uptime percentage (target: 99.9% = 8.7h downtime/year)\n  - Health check status (/health endpoint)\n  - Error rate (5xx / total requests)\n\nperformance:\n  - p50 latency (target: < 100ms)\n  - p95 latency (target: < 500ms)\n  - p99 latency (target: < 1000ms)\n  - Throughput (requests/second)\n  - Time to first byte (TTFB)\n\nbusiness:\n  - Requests per endpoint (usage patterns)\n  - Unique API consumers/day\n  - Error rate by endpoint\n  - Rate limit hits/day\n  - Authentication failures/day\n\ninfrastructure:\n  - Database query time (p95)\n  - Connection pool utilization\n  - Memory/CPU per instance\n  - Queue depth (async operations)\n\nStructured Logging\n\nEvery request should log:\n\n{\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"level\": \"info\",\n  \"request_id\": \"req_abc123\",\n  \"method\": \"POST\",\n  \"path\": \"/api/v1/orders\",\n  \"status\": 201,\n  \"duration_ms\": 45,\n  \"user_id\": \"usr_xyz\",\n  \"ip\": \"203.0.113.1\",\n  \"user_agent\": \"MyApp/2.0\",\n  \"request_size\": 256,\n  \"response_size\": 1024\n}\n\nHealth Check Endpoint\n// GET /health — for load balancers (simple)\n{ \"status\": \"ok\" }\n\n// GET /health/detailed — for monitoring (authenticated)\n{\n  \"status\": \"degraded\",\n  \"version\": \"1.5.2\",\n  \"uptime_seconds\": 86400,\n  \"checks\": {\n    \"database\": { \"status\": \"ok\", \"latency_ms\": 5 },\n    \"redis\": { \"status\": \"ok\", \"latency_ms\": 2 },\n    \"external_payment_api\": { \"status\": \"degraded\", \"latency_ms\": 2500, \"error\": \"timeout\" },\n    \"disk\": { \"status\": \"ok\", \"free_gb\": 45.2 }\n  }\n}\n\nPhase 8: API Review Scoring\n\nWhen reviewing an existing API, score across these dimensions:\n\nAPI Quality Rubric (0-100)\nDimension\tWeight\tCriteria\tScore\nDesign Consistency\t20%\tNaming conventions, HTTP methods, status codes, URL structure\t/20\nDocumentation\t15%\tOpenAPI spec, examples, error docs, changelog\t/15\nError Handling\t15%\tConsistent format, helpful messages, proper codes, no leakage\t/15\nSecurity\t20%\tAuth, input validation, CORS, headers, no IDOR\t/20\nPerformance\t15%\tLatency targets met, pagination, caching headers, N+1 prevented\t/15\nDeveloper Experience\t15%\tSDK quality, sandbox available, onboarding time, rate limit clarity\t/15\n\nScore: ___/100\n\nRating\tScore\tAction\n🟢 Excellent\t85-100\tMinor improvements only\n🟡 Good\t70-84\tAddress gaps before next major release\n🟠 Needs Work\t50-69\tPrioritize improvements, create tech debt tickets\n🔴 Critical\t<50\tStop feature work, fix fundamentals first\nReview Output Template\n## API Review: [Service Name]\n\n**Date:** YYYY-MM-DD\n**Reviewer:** [Agent]\n**Score:** XX/100 (Rating)\n\n### Summary\n[2-3 sentence overview of API quality]\n\n### Scores by Dimension\n- Design Consistency: X/20 — [key finding]\n- Documentation: X/15 — [key finding]\n- Error Handling: X/15 — [key finding]\n- Security: X/20 — [key finding]\n- Performance: X/15 — [key finding]\n- Developer Experience: X/15 — [key finding]\n\n### Critical Issues (fix immediately)\n1. [Issue + recommendation]\n\n### High Priority (fix this sprint)\n1. [Issue + recommendation]\n\n### Nice to Have (backlog)\n1. [Issue + recommendation]\n\n### Positive Highlights\n- [What's working well]\n\nGraphQL-Specific Guidance\nSchema Design Principles\n# Good: clear types, nullable where appropriate, connections for lists\ntype Order {\n  id: ID!\n  status: OrderStatus!\n  customer: Customer!\n  items(first: Int, after: String): ItemConnection!\n  total: Money!\n  createdAt: DateTime!\n  updatedAt: DateTime!\n}\n\ntype Money {\n  amount: Int!       # cents, not dollars (avoid float)\n  currency: Currency!\n}\n\nenum OrderStatus {\n  DRAFT\n  CONFIRMED\n  PROCESSING\n  SHIPPED\n  DELIVERED\n  CANCELLED\n}\n\n# Mutations return the modified resource + errors\ntype CreateOrderPayload {\n  order: Order\n  errors: [UserError!]!\n}\n\ntype UserError {\n  field: [String!]\n  message: String!\n  code: ErrorCode!\n}\n\nGraphQL Anti-Patterns\nAnti-Pattern\tProblem\tFix\nNo depth limit\tQuery bombs\tLimit depth to 5-7 levels\nNo complexity limit\tExpensive queries\tAssign cost per field, cap at 1000\nN+1 queries\tPerformance death\tUse DataLoader pattern\nNo persisted queries\tSecurity risk\tWhitelist queries in production\nExposing internal IDs\tLeaks implementation\tUse opaque global IDs\nNo pagination\tMemory explosion\tUse Relay Connection spec\nEdge Cases & Gotchas\nTimezone Handling\nAlways store and return UTC (ISO 8601: 2024-01-15T10:30:00Z)\nAccept timezone in input, convert to UTC immediately\nNever use local server time\nLarge Payloads\nSet Content-Length limits (e.g., 1MB default, 10MB for uploads)\nUse streaming for file uploads (multipart/form-data)\nCompress responses (Accept-Encoding: gzip)\nFor very large exports → return 202 + poll status endpoint\nEventual Consistency\nIf using async processing, always return 202 + status URL\nInclude estimated completion time when possible\nClient should poll with exponential backoff\nConcurrent Updates\nUse ETags for optimistic concurrency:\nGET returns ETag: \"v1\" header\nPUT/PATCH sends If-Match: \"v1\" header\nServer returns 412 if resource changed since\nWebhook Design\nInclude event type, timestamp, and full resource in payload\nSign payloads (HMAC-SHA256)\nExpect retries (make handlers idempotent)\nReturn 200 quickly, process async\nInclude webhook ID for deduplication\nQuick Commands\nRequest\tAction\n\"Design an API for [domain]\"\tRun Phase 1 resource modeling + naming\n\"Generate OpenAPI spec\"\tRun Phase 2 with full components\n\"Review this API\"\tRun Phase 8 scoring rubric\n\"Write tests for [endpoint]\"\tRun Phase 4 endpoint checklist\n\"Security audit this API\"\tRun Phase 5 security checklist\n\"How should I version this?\"\tRun Phase 6 decision matrix\n\"Debug this API issue\"\tCheck Phase 7 logging + health patterns\n\"Design GraphQL schema for [domain]\"\tRun GraphQL section"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/1kalin/afrexai-api-architect",
    "publisherUrl": "https://clawhub.ai/1kalin/afrexai-api-architect",
    "owner": "1kalin",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/afrexai-api-architect",
    "downloadUrl": "https://openagent3.xyz/downloads/afrexai-api-architect",
    "agentUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent",
    "manifestUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/afrexai-api-architect/agent.md"
  }
}