agentsclimarketplace

Api design

Skill timwukp/agent-skills-best-practice/skills/skills/api-design

35 portable agent skills (Agent Skills spec) for Kiro & Claude Code: Scrum DevSecOps roles, PCI-DSS/MAS TRM compliance, AWS Well-Architected reviews — each with evals and a 4-layer tested methodology

Install
npx -y skills add timwukp/agent-skills-best-practice --skill api-design

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Generates RESTful and GraphQL API designs with OpenAPI specs, proper resource naming, HTTP method usage, status codes, pagination, filtering, error responses, versioning strategies, and GraphQL schema patterns. Triggers on: "design API", "create API spec", "OpenAPI", "REST endpoint design", "GraphQL schema".

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

7.5 KB, as published. Nobody here has run it

API Design

Instructions

Step 1: Gather Requirements

Ask:

  1. What resources does this API manage? (e.g., users, orders, products)
  2. What operations are needed? (CRUD, search, bulk operations, async jobs)
  3. Who consumes it? (internal services, public clients, mobile apps)
  4. Auth model? (API key, OAuth2, JWT)
  5. Output format preference? (OpenAPI 3.0 YAML, endpoint list, or both)

Step 2: Resource Naming

Apply these naming conventions:

RuleGoodBad
Plural nouns/users/user, /getUsers
Nested resources/users/{id}/orders/getUserOrders
Lowercase with hyphens/order-items/orderItems, /order_items
No verbs in URLs/users/{id}/activate (POST)/activateUser
Max 3 levels deep/users/{id}/orders/users/{id}/orders/{id}/items/{id}/reviews

For deeply nested resources, promote to top-level with query filters:

GET /reviews?order_id=123&user_id=456

Step 3: HTTP Methods and Status Codes

Map operations to methods:

OperationMethodSuccess CodeResponse Body
List/SearchGET200Collection
Get singleGET200Resource
CreatePOST201Created resource + Location header
Full updatePUT200Updated resource
Partial updatePATCH200Updated resource
DeleteDELETE204Empty
Async operationPOST202Job status + Location header

Error codes to use consistently:

  • 400 - Malformed request (bad JSON, missing required field)
  • 401 - Not authenticated
  • 403 - Authenticated but not authorized
  • 404 - Resource not found
  • 409 - Conflict (duplicate, version mismatch)
  • 422 - Valid JSON but failed business validation
  • 429 - Rate limited
  • 500 - Server error (never expose internals)

Step 4: Pagination, Filtering, and Sorting

Pagination (cursor-based preferred for large datasets):

GET /orders?cursor=eyJpZCI6MTAwfQ&limit=25

Response:
{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTI1fQ",
    "has_more": true
  }
}

Offset pagination (simpler, fine for small datasets):

GET /orders?page=2&per_page=25

Response:
{
  "data": [...],
  "pagination": {
    "page": 2,
    "per_page": 25,
    "total": 142,
    "total_pages": 6
  }
}

Filtering and sorting:

GET /orders?status=pending&created_after=2024-01-01&sort=-created_at,+total
  • Use query parameters for filtering
  • Prefix sort fields with - for descending, + for ascending
  • Document all available filter fields

Step 5: Error Response Format

Use a consistent error envelope:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The request body contains invalid fields",
    "details": [
      {
        "field": "email",
        "issue": "must be a valid email address",
        "value": "not-an-email"
      }
    ],
    "request_id": "req_abc123",
    "documentation_url": "https://api.example.com/docs/errors#VALIDATION_FAILED"
  }
}

Rules:

  • Machine-readable code (UPPER_SNAKE_CASE)
  • Human-readable message
  • Field-level details for validation errors
  • Include request_id for debugging
  • Never expose stack traces, SQL, or internal paths

Step 6: Generate OpenAPI Spec

Produce an OpenAPI 3.0 specification:

openapi: 3.0.3
info:
  title: [Service Name] API
  version: 1.0.0
  description: [Brief description]
paths:
  /resources:
    get:
      summary: List resources
      operationId: listResources
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 25
            maximum: 100
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceList'
components:
  schemas:
    Resource:
      type: object
      required: [id, name]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string

Step 7: Versioning Strategy

Recommend URL-path versioning for most cases:

/v1/users
/v2/users

When to create a new version:

  • Removing a field from responses
  • Changing a field type
  • Removing an endpoint
  • Changing authentication mechanism

When NOT to version (additive changes):

  • Adding new optional fields
  • Adding new endpoints
  • Adding new query parameters

Step 8: GraphQL Schema Design

When the consumer needs flexible queries or the API serves multiple clients with different data needs, offer a GraphQL alternative:

Schema definition:

type Query {
  book(id: ID!): Book
  books(filter: BookFilter, first: Int = 25, after: String): BookConnection!
}

type Mutation {
  createBook(input: CreateBookInput!): BookPayload!
  updateBook(id: ID!, input: UpdateBookInput!): BookPayload!
  deleteBook(id: ID!): DeletePayload!
}

type Book {
  id: ID!
  title: String!
  author: Author!
  publishedAt: DateTime
  isbn: String
}

input BookFilter {
  title: String
  authorId: ID
  publishedAfter: DateTime
}

input CreateBookInput {
  title: String!
  authorId: ID!
  isbn: String
}

type BookConnection {
  edges: [BookEdge!]!
  pageInfo: PageInfo!
}

type BookEdge {
  node: Book!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}

type BookPayload {
  book: Book
  errors: [UserError!]!
}

type UserError {
  field: [String!]
  message: String!
}

GraphQL design rules:

  • Use Relay-style connections (edges/nodes/pageInfo) for paginated lists
  • Return payload types from mutations with both the result and possible errors
  • Mark non-nullable fields with ! only when truly always present
  • Use input types for mutation arguments
  • Prefer specific scalar types (DateTime, URL, Email) over raw String where applicable
  • Nest related data naturally; let the client choose depth via the query

When to choose GraphQL over REST:

  • Multiple clients need different subsets of the same data
  • Deeply nested relationships are common
  • Reducing over-fetching is critical for performance (mobile clients)
  • Rapid iteration on client needs without backend changes

When to prefer REST:

  • Simple CRUD with uniform consumers
  • File uploads or streaming responses
  • Strong caching requirements (HTTP caching is simpler with REST)
  • Team is more familiar with REST conventions

Example

User says: "Design an API for a bookstore"

Response includes:

  • Resource list: books, authors, orders, customers
  • Endpoints: GET /v1/books, POST /v1/orders, etc.
  • OpenAPI snippet for the books resource
  • Error response format
  • Pagination on list endpoints

Guidelines

  • Always use plural nouns for resource names
  • Prefer cursor pagination for datasets that change frequently
  • Use 422 for business logic validation, 400 for malformed requests
  • Include rate limiting headers in responses (X-RateLimit-Remaining, X-RateLimit-Reset)
  • Design for the consumer, not the database schema
  • Every endpoint must have a defined error response
  • Keep the OpenAPI spec as the source of truth, generate docs from it

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.