Developer pack
Claude SkillUpdated today

API and Interface Design

Design API contracts and module boundaries before implementation — interfaces that are hard to misuse, with one error strategy, boundary validation, and additive-only evolution.

What it does

Guides contract-first design for any public interface: REST or GraphQL endpoints, module boundaries between teams, component props, and type contracts between frontend and backend. The organizing idea is Hyrum's Law — with enough consumers, every observable behavior of an interface gets depended on, whatever the written contract promises — so the skill forces intentional decisions about what is exposed. It works through five commitments: define the contract before the implementation; pick one error strategy and apply it universally (structured error bodies, machine-readable codes, consistent status-code mapping); validate at system boundaries and trust internal code; evolve by adding optional fields rather than modifying existing ones; and keep naming predictable (plural-noun REST resources, camelCase fields, is/has/can booleans, UPPER_SNAKE enums). It also enforces pagination on list endpoints from the first version and, for TypeScript contracts, discriminated unions, separated input/output schemas, and branded ID types. Distinct from api-documentation-writer (documents an interface that already exists), adr-writer (records a decision after it is made), and codebase-architecture-reviewer (reviews module depth in existing code): this skill shapes the contract itself, before any of that exists.

When to use

  • Before implementing a new API endpoint or service boundary — the contract review is cheapest while it is still a sketch
  • When two teams (or frontend and backend) need a stable agreement to build against in parallel
  • When changing an existing public interface — the skill routes the change toward additive evolution instead of a breaking modification
  • When a database schema is about to leak directly into an API response shape and nobody has decided whether that is intentional

When not to use

  • Internal helper functions with one or two call sites — boundary rigor there is ceremony; refactor freely instead
  • Throwaway prototypes where the interface will not survive the week; contract-first discipline slows discovery without protecting anyone
  • Documenting an interface that already shipped — that is api-documentation-writer's job, and redesigning it mid-documentation invites breaking changes

Install

Download the .zip, then unzip into your Claude skills folder.

mkdir -p ~/.claude/skills
unzip ~/Downloads/api-and-interface-design.zip -d ~/.claude/skills/

# Restart Claude Code session.
# Skill is now available — Claude will use it when relevant.

SKILL.md

SKILL.md
---
name: api-and-interface-design
description: Use when designing APIs, module boundaries, or any public interface before implementation. Triggers on "design this endpoint", "API contract", "interface between", REST or GraphQL endpoint creation, type contracts between modules, or changes to an existing public interface.
---

# API and Interface Design

An interface is a promise, and Hyrum's Law sets the terms: with a sufficient number of consumers, every observable behavior of your system will be depended on by somebody, regardless of what the contract says. Design is therefore the act of deciding, deliberately, what to expose. Everything exposed by accident is still a commitment.

## The five commitments

### 1. Contract first
Write the interface before the implementation. The contract is the specification: typed request and response schemas, error shapes, and naming, committed before handler code exists. Types are documentation; "we will document it later" means the implementation becomes the contract by default.

### 2. One error strategy
Pick one error format and apply it to every endpoint. A structured body with a machine-readable code and a human-readable message, plus a consistent status-code mapping: 400 malformed input, 401 unauthenticated, 403 unauthorized, 404 missing, 409 conflict, 422 validation failure, 500 server fault. An API where each endpoint fails differently forces every consumer to write per-endpoint error handling.

### 3. Validate at boundaries
Validate where external input enters the system — API handlers, form submissions, environment variables, and every third-party API response, which is untrusted data no matter how reputable the vendor. Inside the boundary, trust your own code. Validation scattered through internal layers is noise that hides the one place validation actually matters.

### 4. Additive evolution
Extend interfaces with new optional fields. Do not change the type of an existing field, and do not remove a field consumers have seen. When behavior must genuinely change, add the new shape alongside the old and plan the deprecation — deprecation is a design-time concern, not an afterthought. Related: avoid forcing consumers to choose between multiple live versions of the same contract; one version at a time, extended rather than forked.

### 5. Predictable naming
- REST resources: plural nouns, no verbs in URLs
- Query parameters and response fields: camelCase
- Booleans: is/has/can prefixes
- Enum values: UPPER_SNAKE

## REST patterns

```
GET    /api/tasks            list (paginated, filterable)
POST   /api/tasks            create
GET    /api/tasks/:id        retrieve
PATCH  /api/tasks/:id        partial update — only provided fields change
DELETE /api/tasks/:id        delete
GET    /api/tasks/:id/comments   sub-resource
```

List endpoints paginate from version one (page, pageSize, totalItems, totalPages in the response). Retrofitting pagination onto an unpaginated endpoint is a breaking change; shipping it on day one is a few lines. Filters go in query parameters: `?status=in_progress&assignee=user123`.

## TypeScript contract patterns

- **Discriminated unions** for variants — a `status` or `type` discriminator gives consumers type narrowing instead of optional-field guessing.
- **Input/output separation** — the type a caller submits is not the type the server returns; server-generated fields (id, createdAt) belong only in the output type.
- **Branded ID types** — brand ID strings so an orderId cannot be passed where a paymentId belongs; the compiler catches the swap.

## Red flags

- An endpoint that returns different shapes depending on internal conditions
- Error formats that differ between endpoints
- Validation logic scattered through internal layers
- A changed field type or a removed field on a shipped interface
- A list endpoint without pagination
- Verbs in REST URLs
- A third-party API response used without validation

## Verification checklist

- [ ] Every endpoint has typed input and output schemas, committed with (or before) the implementation
- [ ] Error responses follow one format, everywhere
- [ ] Validation happens at boundaries; internal layers trust their inputs
- [ ] List endpoints paginate
- [ ] Every change to a shipped interface is additive and optional
- [ ] Naming follows the conventions above without exceptions

## Scope

This skill shapes contracts before implementation. Documenting a shipped interface is api-documentation-writer's job; recording why a design was chosen is adr-writer's; reviewing module depth in existing code is codebase-architecture-reviewer's. Use this one while the interface is still cheap to change.

Example prompts

Once installed, try these prompts in Claude:

  • I am designing POST /api/invoices and GET /api/invoices for our billing service. Apply api-and-interface-design: propose the contract (request/response schemas, error format, pagination) before I write any handler code, and flag anything a consumer could grow to depend on that we do not want to promise.
  • Our frontend team keeps breaking when we change this endpoint. Review the current response shape against Hyrum's Law: what observable behaviors are we implicitly promising, and how do we evolve the interface additively from here?
  • Design the TypeScript contract between our checkout module and the payments module — discriminated unions for the payment states, separate input and output types, and branded IDs so an orderId can never be passed where a paymentId belongs.
Recent changes
  • Jul 14, 2026New skill — contract-first API and interface design: Hyrum's Law, one error strategy, boundary validation, additive-only evolution, TypeScript contract patterns.