api-designer

Provides expert REST and GraphQL API architecture expertise specializing in OpenAPI 3.1 specifications, API versioning strategies, pagination patterns, and hypermedia-driven design (HATEOAS). Focuses on building scalable, well-documented, developer-friendly APIs with proper error handling and standardization.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "api-designer" with this command: npx skills add neversight/skills_feed/neversight-skills-feed-api-designer

API Designer

Purpose

Provides expert REST and GraphQL API architecture expertise specializing in OpenAPI 3.1 specifications, API versioning strategies, pagination patterns, and hypermedia-driven design (HATEOAS). Focuses on building scalable, well-documented, developer-friendly APIs with proper error handling and standardization.

When to Use

  • Designing RESTful or GraphQL APIs from requirements

  • Creating OpenAPI 3.1 specifications for API documentation

  • Implementing API versioning strategies (URL, header, content negotiation)

  • Designing pagination, filtering, and sorting patterns for large datasets

  • Building HATEOAS-compliant APIs (hypermedia-driven)

  • Standardizing error responses and status codes across services

  • Designing API authentication and authorization patterns

Quick Start

Invoke this skill when:

  • Designing RESTful or GraphQL APIs from requirements

  • Creating OpenAPI 3.1 specifications for API documentation

  • Implementing API versioning strategies (URL, header, content negotiation)

  • Designing pagination, filtering, and sorting patterns for large datasets

  • Building HATEOAS-compliant APIs (hypermedia-driven)

  • Standardizing error responses and status codes across services

Do NOT invoke when:

  • Only implementing pre-designed API endpoints (use backend-developer)

  • Database schema design without API context (use database-administrator)

  • Frontend API integration (use frontend-developer)

  • API security implementation (use security-engineer for authentication/authorization)

  • API performance optimization (use performance-engineer)

Core Workflows

Workflow 1: Design RESTful API with OpenAPI 3.1

Use case: E-commerce platform needs product catalog API

Step 1: Resource Modeling

Resources identified:

- Products (CRUD)

- Categories (read-only, hierarchical)

- Reviews (nested under products)

- Inventory (separate resource, linked to products)

URL Structure Design:

GET /v1/products # List products (paginated) POST /v1/products # Create product GET /v1/products/{id} # Get product details PUT /v1/products/{id} # Update product (full replacement) PATCH /v1/products/{id} # Partial update DELETE /v1/products/{id} # Delete product

GET /v1/products/{id}/reviews # Get reviews for product POST /v1/products/{id}/reviews # Create review GET /v1/products/{id}/reviews/{reviewId} # Get specific review

GET /v1/categories # List categories GET /v1/categories/{id} # Get category + subcategories

Query parameters (filtering, pagination, sorting):

GET /v1/products?category=electronics&min_price=100&max_price=500&sort=price:asc&limit=20&cursor=abc123

Step 2: OpenAPI 3.1 Specification

openapi.yaml

openapi: 3.1.0 info: title: E-commerce Product API version: 1.0.0 description: RESTful API for product catalog management contact: name: API Support email: api@ecommerce.com

servers:

paths: /products: get: summary: List products operationId: listProducts tags: [Products] parameters: - name: category in: query description: Filter by category slug schema: type: string example: electronics - name: min_price in: query description: Minimum price filter schema: type: number format: float minimum: 0 - name: max_price in: query description: Maximum price filter schema: type: number format: float minimum: 0 - name: sort in: query description: Sort order (field:direction) schema: type: string enum: [price:asc, price:desc, created_at:asc, created_at:desc] default: created_at:desc - name: limit in: query description: Number of results per page schema: type: integer minimum: 1 maximum: 100 default: 20 - name: cursor in: query description: Pagination cursor (opaque token) schema: type: string responses: '200': description: Successful response content: application/json: schema: type: object required: [data, meta, links] properties: data: type: array items: $ref: '#/components/schemas/Product' meta: type: object properties: total_count: type: integer description: Total number of products matching filters has_more: type: boolean description: Whether more results exist links: type: object properties: self: type: string format: uri next: type: string format: uri nullable: true prev: type: string format: uri nullable: true examples: success: value: data: - id: "prod_123" name: "Wireless Headphones" description: "Premium noise-cancelling headphones" price: 299.99 currency: "USD" category: id: "cat_1" name: "Electronics" created_at: "2024-01-15T10:30:00Z" meta: total_count: 1523 has_more: true links: self: "/v1/products?limit=20" next: "/v1/products?limit=20&cursor=eyJpZCI6InByb2RfMTIzIn0=" prev: null '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError'

/products/{id}: get: summary: Get product details operationId: getProduct tags: [Products] parameters: - name: id in: path required: true description: Product ID schema: type: string pattern: '^prod_[a-zA-Z0-9]+$' responses: '200': description: Product found content: application/json: schema: $ref: '#/components/schemas/Product' '404': $ref: '#/components/responses/NotFound'

components: schemas: Product: type: object required: [id, name, price, currency] properties: id: type: string description: Unique product identifier example: "prod_123" name: type: string minLength: 1 maxLength: 200 example: "Wireless Headphones" description: type: string maxLength: 2000 nullable: true price: type: number format: float minimum: 0 example: 299.99 currency: type: string enum: [USD, EUR, GBP, JPY] default: USD category: $ref: '#/components/schemas/Category' images: type: array items: type: string format: uri maxItems: 10 inventory_count: type: integer minimum: 0 description: Available stock created_at: type: string format: date-time updated_at: type: string format: date-time

Category:
  type: object
  required: [id, name, slug]
  properties:
    id:
      type: string
      example: "cat_1"
    name:
      type: string
      example: "Electronics"
    slug:
      type: string
      pattern: '^[a-z0-9-]+$'
      example: "electronics"
    parent_id:
      type: string
      nullable: true

Error:
  type: object
  required: [error]
  properties:
    error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: "invalid_parameter"
        message:
          type: string
          description: Human-readable error message
          example: "The 'price' parameter must be a positive number"
        details:
          type: object
          description: Additional error context
          additionalProperties: true

responses: BadRequest: description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "invalid_parameter" message: "The 'min_price' parameter must be a non-negative number" details: parameter: "min_price" value: "-10"

NotFound:
  description: Resource not found
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/Error'
      example:
        error:
          code: "resource_not_found"
          message: "Product with ID 'prod_999' not found"

InternalServerError:
  description: Internal server error
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/Error'
      example:
        error:
          code: "internal_server_error"
          message: "An unexpected error occurred. Please try again later."
          details:
            request_id: "req_abc123"

securitySchemes: ApiKey: type: apiKey in: header name: X-API-Key BearerAuth: type: http scheme: bearer bearerFormat: JWT

security:

  • ApiKey: []
  • BearerAuth: []

Step 3: Generate Documentation

Install Redoc CLI

npm install -g redoc-cli

Generate static HTML documentation

redoc-cli bundle openapi.yaml -o api-docs.html

Host documentation

npx serve api-docs.html

Interactive Swagger UI

docker run -p 8080:8080 -e SWAGGER_JSON=/docs/openapi.yaml
-v $(pwd):/docs swaggerapi/swagger-ui

Open http://localhost:8080 for interactive API testing

Anti-Patterns & Gotchas

❌ Anti-Pattern 1: Inconsistent Error Responses

What it looks like:

// Endpoint 1: Login failure { "error": "Invalid credentials" }

// Endpoint 2: Validation failure { "errors": [ { "field": "email", "message": "Invalid email format" } ] }

// Endpoint 3: Server error { "status": "error", "message": "Internal server error", "code": 500 }

// Problem: Clients need custom error handling per endpoint

Why it fails:

  • Client code becomes complex (multiple error parsing strategies)

  • Frontend developers frustrated (inconsistent contracts)

  • Error logging/monitoring difficult (no standard format)

Correct approach:

// Standardized error response (all endpoints) { "error": { "code": "invalid_credentials", "message": "The provided email or password is incorrect", "details": null, "request_id": "req_abc123" } }

// Validation errors (multiple fields) { "error": { "code": "validation_failed", "message": "One or more fields failed validation", "details": { "fields": [ { "field": "email", "message": "Invalid email format" }, { "field": "password", "message": "Password must be at least 8 characters" } ] }, "request_id": "req_def456" } }

// Client-side error handling (consistent) function handleApiError(response) { const { code, message, details } = response.error;

switch (code) { case 'validation_failed': // Display field-specific errors details.fields.forEach(({ field, message }) => { showFieldError(field, message); }); break;

case 'unauthorized':
  // Redirect to login
  redirectToLogin();
  break;

default:
  // Generic error message
  showToast(message);

} }

Integration Patterns

backend-developer:

  • Handoff: API designer creates spec → Backend implements endpoints

  • Collaboration: Error response formats, authentication patterns

  • Tools: OpenAPI code generation, API mocking

frontend-developer:

  • Handoff: API spec published → Frontend consumes API

  • Collaboration: Query patterns, pagination, error handling

  • Tools: TypeScript type generation from OpenAPI/GraphQL schema

security-engineer:

  • Handoff: API designer defines authentication needs → Security implements auth

  • Collaboration: Rate limiting, API key management, OAuth flows

  • Critical: JWT validation, API gateway security policies

devops-engineer:

  • Handoff: API design finalized → DevOps deploys API gateway

  • Collaboration: API versioning deployment, blue-green releases

  • Tools: Kong, AWS API Gateway, Traefik configuration

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

python-env

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

typescript-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

_skillwriting

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review