review-notes
This shows how the api-designer agent reviews a flawed draft. Findings are severity-ranked so the implementer fixes the contract-breakers first. Severity legend: **CRITICAL** (breaks clients / data risk), **HIGH** (real bug or inconsistency), **MEDIUM** (maintainability),
$ npx -y skills add vanara-agents/skills --agent claude-codeHow it fires
How this agent 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.
Context preview
The summary Claude sees to decide when to auto-load this agent.
This shows how the api-designer agent reviews a flawed draft. Findings are severity-ranked so the implementer fixes the contract-breakers first. Severity legend: **CRITICAL** (breaks clients / data risk), **HIGH** (real bug or inconsistency), **MEDIUM** (maintainability),
Agent definition
review-notes.mdReview Notes — Critiquing a Draft Contract
This shows how the api-designer agent reviews a flawed draft. Findings are severity-ranked so the implementer fixes the contract-breakers first. Severity legend: **CRITICAL** (breaks clients / data risk), **HIGH** (real bug or inconsistency), **MEDIUM** (maintainability), **LOW** (style).
The draft under review
POST /createOrder → 200 { "success": true, "order": {...} }
GET /getOrders → 200 [ {...}, {...}, ... ] # entire table
POST /refundOrder → 200 { "success": false, "msg": "already refunded" }
GET /orders/{id} → 200 { "id": 41, "status": "open" }
DELETE /orders/{id} → 200 { "success": true }Findings
CRITICAL
1. **`200 OK` with `{"success": false}` on refund.** A failed refund returns HTTP 200, so every client that checks the status code treats a failure as success. Use a real code — `409 Conflict` for "already refunded" — with the standard error envelope. *Fix:* `POST /orders/{id}/refunds → 201` on success, `409` + `{ "data": null, "error": { "code": "already_refunded", ... } }` on conflict.
2. **Unbounded `GET /getOrders` returns the entire table.** No pagination and no `limit` cap is a self-inflicted DoS as the table grows. *Fix:* `GET /orders?limit=20&cursor=...` with `limit` capped server-side at 100, returning the list envelope with `meta.nextCursor`.
HIGH
3. **Verbs in URLs** (`/createOrder`, `/getOrders`, `/refundOrder`). The HTTP method is the verb; paths are nouns. *Fix:* `POST /orders`, `GET /orders`, `POST /orders/{id}/refunds`.
4. **Inconsistent response shapes.** `GET /getOrders` returns a bare array; other endpoints return objects with ad-hoc keys (`order`, `success`, `msg`). Clients can't generalize. *Fix:* one envelope everywhere — `{ data, meta, error }`.
5. **Wrong success codes.** `POST /createOrder` returns 200 with no `Location`; it creates a resource so it should be `201 Created` + `Location: /orders/{id}`. `DELETE` should be `204 No Content`.
MEDIUM
6. **Enumerable integer IDs** (`"id": 41`). Sequential IDs leak volume and invite enumeration attacks. *Fix:* opaque IDs (`ord_01H...`, UUID/ULID).
7. **No idempotency on create.** A retried `POST /orders` will double-create. *Fix:* accept an `Idempotency-Key` header.
LOW
8. **Inconsistent error key** (`msg` vs the rest of the API). Standardize on `error.message`.
Rewritten contract
See `openapi-snippet.yaml` in this package for the corrected version: plural nouns, `201`/`204`/`409` status codes, cursor pagination with a capped `limit`, the single `{ data, meta, error }` envelope, opaque IDs, and an `Idempotency-Key` on create.
Read more
Review Notes — Critiquing a Draft Contract
This shows how the api-designer agent reviews a flawed draft. Findings are severity-ranked so the implementer fixes the contract-breakers first. Severity legend: **CRITICAL** (breaks clients / data risk), **HIGH** (real bug or inconsistency), **MEDIUM** (maintainability), **LOW** (style).
The draft under review
POST /createOrder → 200 { "success": true, "order": {...} }
GET /getOrders → 200 [ {...}, {...}, ... ] # entire table
POST /refundOrder → 200 { "success": false, "msg": "already refunded" }
GET /orders/{id} → 200 { "id": 41, "status": "open" }
DELETE /orders/{id} → 200 { "success": true }Findings
CRITICAL
1. **`200 OK` with `{"success": false}` on refund.** A failed refund returns HTTP 200, so every client that checks the status code treats a failure as success. Use a real code — `409 Conflict` for "already refunded" — with the standard error envelope. *Fix:* `POST /orders/{id}/refunds → 201` on success, `409` + `{ "data": null, "error": { "code": "already_refunded", ... } }` on conflict.
2. **Unbounded `GET /getOrders` returns the entire table.** No pagination and no `limit` cap is a self-inflicted DoS as the table grows. *Fix:* `GET /orders?limit=20&cursor=...` with `limit` capped server-side at 100, returning the list envelope with `meta.nextCursor`.
HIGH
3. **Verbs in URLs** (`/createOrder`, `/getOrders`, `/refundOrder`). The HTTP method is the verb; paths are nouns. *Fix:* `POST /orders`, `GET /orders`, `POST /orders/{id}/refunds`.
4. **Inconsistent response shapes.** `GET /getOrders` returns a bare array; other endpoints return objects with ad-hoc keys (`order`, `success`, `msg`). Clients can't generalize. *Fix:* one envelope everywhere — `{ data, meta, error }`.
5. **Wrong success codes.** `POST /createOrder` returns 200 with no `Location`; it creates a resource so it should be `201 Created` + `Location: /orders/{id}`. `DELETE` should be `204 No Content`.
MEDIUM
6. **Enumerable integer IDs** (`"id": 41`). Sequential IDs leak volume and invite enumeration attacks. *Fix:* opaque IDs (`ord_01H...`, UUID/ULID).
7. **No idempotency on create.** A retried `POST /orders` will double-create. *Fix:* accept an `Idempotency-Key` header.
LOW
8. **Inconsistent error key** (`msg` vs the rest of the API). Standardize on `error.message`.
Rewritten contract
See `openapi-snippet.yaml` in this package for the corrected version: plural nouns, `201`/`204`/`409` status codes, cursor pagination with a capped `limit`, the single `{ data, meta, error }` envelope, opaque IDs, and an `Idempotency-Key` on create.
🐒 Free agents, skills & packs for Claude Code One subscription. An army of Claude Code agents. 30 production-grade agents, skills, and packs for Claude Code — free, Apache-2.0, install with one command.
Repo: vanara-agents/skills
Other agents on vanara-agents-skills.
- AGENT
Use when designing a new HTTP/GraphQL API or changing an existing one — modeling resources, defining endpoint contracts, choosing status codes, pagination, filtering, error envelopes, versioning, and idempotency. Produces a reviewable API contract plus an OpenAPI snippet, not
Open agent - contract-and-openapi
The contract is the deliverable. Express it as an **OpenAPI 3.1** document so it is human-readable *and* machine-checkable. This reference covers how to structure that document and what `scripts/lint-openapi.mjs` enforces.
Open agent - design-checklist
Run through this before declaring an API contract done. It is ordered the way you should *design*: resources first, cross-cutting rules last. Every box is a place real APIs go wrong in production.
Open agent - versioning-and-evolution
APIs are forever once published: a consumer you've never met may depend on any field you expose. Design so you can **add without breaking**, and version explicitly when you must break.
Open agent - pr-comment-template
Copy-paste templates for leaving review comments. Keep each comment to one finding: an anchor, the problem, and the fix.
Open agent - sample-review-output
A complete review of a hypothetical PR, in the standard format. Use this as the model for tone, structure, and the anchor → problem → fix pattern.
Open agent

