Skip to content
Agent Orchestration
Skill

/designing-apis

Guides REST and GraphQL API design, endpoint patterns, request/response schemas, versioning, and API best practices. Use when building APIs, designing endpoints, or reviewing API contracts.

BOOST
From plugin
opencode-workflow
2757 skills7 agents12 commands
Install
$ npx -y skills add cloudai-x/opencode-workflow --skill designing-apis --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/designing-apis

Context preview

The summary Claude sees to decide when to auto-load this skill.

Guides REST and GraphQL API design, endpoint patterns, request/response schemas, versioning, and API best practices. Use when building APIs, designing endpoints, or reviewing API contracts.

SKILL.md

designing-apis.SKILL.md
name: designing-apis
description: Guides REST and GraphQL API design, endpoint patterns, request/response schemas, versioning, and API best practices. Use when building APIs, designing endpoints, or reviewing API contracts.
license: MIT
compatibility: opencode
metadata:
  category: design
  audience: developers

Designing APIs

Principles and patterns for designing clean, consistent, and maintainable APIs.

When to Use This Skill

  • Designing new API endpoints
  • Reviewing API contracts
  • Planning API versioning strategies
  • Defining request/response schemas
  • Building GraphQL schemas
  • Documenting APIs

---

REST API Design Principles

Resource-Oriented Design

APIs should be organized around **resources**, not actions:

GOOD (Resource-oriented):
GET    /users           → List users
GET    /users/123       → Get user 123
POST   /users           → Create user
PUT    /users/123       → Update user 123
DELETE /users/123       → Delete user 123

BAD (Action-oriented):
POST   /getUsers
POST   /createUser
POST   /updateUser
POST   /deleteUser

HTTP Method Semantics

| Method | Purpose | Idempotent | Safe | Request Body | |--------|---------|------------|------|--------------| | GET | Retrieve resource(s) | Yes | Yes | No | | POST | Create resource | No | No | Yes | | PUT | Replace resource | Yes | No | Yes | | PATCH | Partial update | Yes | No | Yes | | DELETE | Remove resource | Yes | No | Optional |

URL Structure Patterns

Collection:     /users
Item:           /users/{id}
Nested:         /users/{id}/posts
Action:         /users/{id}/activate (POST only, for non-CRUD)
Filter:         /users?status=active&role=admin
Pagination:     /users?page=2&limit=20
Sort:           /users?sort=created_at&order=desc

---

Request Design

Path Parameters vs Query Parameters

| Use | Path Parameters | Query Parameters | |-----|-----------------|------------------| | Resource identification | `/users/123` | - | | Required filters | `/orgs/456/users` | - | | Optional filters | - | `?status=active` | | Pagination | - | `?page=2&limit=20` | | Sorting | - | `?sort=name&order=asc` | | Search | - | `?q=searchterm` |

Request Body Patterns

// POST /users - Create
{
  "email": "user@example.com",
  "name": "John Doe",
  "role": "admin"
}

// PATCH /users/123 - Partial update
{
  "name": "Jane Doe"
}

// Bulk operations - POST /users/bulk
{
  "operations": [
    { "action": "create", "data": { "email": "..." } },
    { "action": "update", "id": "123", "data": { "name": "..." } }
  ]
}

---

Response Design

Consistent Response Envelope

// Success response
{
  "data": { ... },
  "meta": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "abc123"
  }
}

// Collection response with pagination
{
  "data": [ ... ],
  "meta": {
    "total": 100,
    "page": 2,
    "limit": 20,
    "hasMore": true
  }
}

// Error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": [
      { "field": "email", "message": "Invalid email format" }
    ]
  },
  "meta": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "abc123"
  }
}

HTTP Status Code Guidelines

| Range | Category | Common Codes | |-------|----------|--------------| | 2xx | Success | 200 OK, 201 Created, 204 No Content | | 3xx | Redirect | 301 Moved, 304 Not Modified | | 4xx | Client Error | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Unprocessable | | 5xx | Server Error | 500 Internal, 502 Bad Gateway, 503 Unavailable |

Status Code Decision Tree

Success?
├─ Yes
│  ├─ Returning data? → 200 OK
│  ├─ Created resource? → 201 Created
│  └─ No content? → 204 No Content
└─ No
   ├─ Client's fault?
   │  ├─ Bad syntax? → 400 Bad Request
   │  ├─ Not authenticated? → 401 Unauthorized
   │  ├─ Not authorized? → 403 Forbidden
   │  ├─ Not found? → 404 Not Found
   │  └─ Validation failed? → 422 Unprocessable Entity
   └─ Server's fault? → 500 Internal Server Error

---

API Versioning Strategies

URL Path Versioning (Recommended)

/api/v1/users
/api/v2/users

**Pros**: Explicit, easy to understand, easy to route **Cons**: URL changes between versions

Header Versioning

GET /api/users
Accept: application/vnd.myapi.v2+json

**Pros**: Clean URLs **Cons**: Hidden version, harder to test

Query Parameter Versioning

/api/users?version=2

**Pros**: Flexible, easy to test **Cons**: Can be forgotten, pollutes query string

---

GraphQL Design Patterns

Schema-First Design

type User {
  id: ID!
  email: String!
  name: String!
  posts: [Post!]!
  createdAt: DateTime!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  createdAt: DateTime!
}

type Query {
  user(id: ID!): User
  users(filter: UserFilter, page: PageInput): UserConnection!
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
}

Input Types Pattern

input CreateUserInput {
  email: String!
  name: String!
  role: Role = USER
}

input UpdateUserInput {
  email: String
  name: String
  role: Role
}

input UserFilter {
  status: UserStatus
  role: Role
  search: String
}

Pagination Patterns

# Cursor-based (recommended for large datasets)
type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

# Offset-based (simpler, for smaller datasets)
type UserList {
  items: [User!]!
  total: Int!
  page: Int!
  limit: Int!
}

---

Authentication & Authorization

Authentication Patterns

| Pattern | Use Case | Header | |---------|----------|--------| | Bearer Token | Standard API auth | `Authorization: Bearer <token>` | | API Key | Server-to

Read more
Ships withopencode-workflow

A universal OpenCode workflow setup with specialized agents, skills, commands, and plugins for any software project.

Get the whole plugin

Other skills on opencode-workflow.