Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when authoring or reviewing the operations of an OpenAPI (Swagger) 3.x description: give every operation a unique camelCase verbNoun operationId, declare each {path} parameter as in: path with required: true, group operations with tags, document responses for both a success and an error status code, and define reusable objects once under components/schemas (PascalCase) referenced by $ref — which cheaper models skip by default. Do NOT use for choosing REST URL versioning schemes, for generic resource-and-collection URL naming, or for generating client SDK code from an existing spec.
.claude/skills/openapi-operation-conventions/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 4 |
| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | +4% | +63% | 0% | 23 | 54d ago |
| gemini-3.5-flash | pending re-run | — | |||
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✓→✓ | = Same ✓ | — | — |
| case-19 | ✗→✗ | = Same ✗ | — | — |
| case-06 | ✗→✗ | = Same ✗ | — | — |
| case-21 | ✗→✗ | = Same ✗ | — | — |
Author every operation in an OpenAPI 3.x description to the disciplined form: a unique camelCase verbNoun operationId, every {path} parameter declared with in: path and required: true, tags grouping, responses documented for both a success and an error status code, and reusable object schemas defined once under components/schemas (PascalCase) and referenced by $ref. Apply when writing or reviewing the operations of a spec; not for choosing URL versioning, generic resource naming, or generating client code from a spec.
operationId. No operation is left without one — it is the stablehandle generators and docs key on.
operationId is camelCase verbNoun. A leading verb, then the noun: listUsers, getUser,createUser, updateUser, deleteUser, listUserOrders. Not snake_case, not the noun first (userGet), not a sentence.
operationIds are unique across the whole document. Two similar operations get distinctids (listActiveUsers, listArchivedUsers) — never the same id twice.
{path} parameter is declared. A templated segment like /users/{userId} has amatching entry under parameters with name: userId, in: path, required: true, and a schema. in: path parameters are always required: true.
tags. Each operation carries at least one tag (Users,Orders), so the rendered docs and generated clients group related operations.
responses is keyed by HTTP status code and lists atleast one success code (a 2xx) and at least one error code (a 4xx/5xx). Never only a bare 200. Each operation also has a short summary.
components/schemas, referenced by $ref. An object used inmore than one place is defined once under components/schemas with a PascalCase key (User, Order, Error) and referenced everywhere via $ref: '#/components/schemas/User' — never re-inlined per operation.
Operation identity and path parameter — the thin default, then the conforming operation:
yaml# BEFORE /users/{userId}: get: summary: Get a user responses: '200': { description: OK } # AFTER /users/{userId}: get: operationId: getUser summary: Get a user tags: [Users] parameters: - name: userId in: path required: true schema: { type: string } responses: '200': description: The user content: application/json: schema: { $ref: '#/components/schemas/User' } '404': { description: User not found }
Schema reuse — inlined twice vs. one components/schemas entry:
yaml# BEFORE (the same object re-declared inline in each operation) responses: '200': content: application/json: schema: type: object properties: { id: { type: string }, name: { type: string } } # AFTER components: schemas: User: type: object properties: { id: { type: string }, name: { type: string } } # ...and each operation references it: schema: { $ref: '#/components/schemas/User' }
Unique ids for similar operations:
yaml# BEFORE operationId: listUsers (on BOTH operations) # AFTER operationId: listActiveUsers / operationId: listArchivedUsers
/orgs/{orgId}/members/{memberId}) declares BOTH asin: path, required: true.
in: query / in: header; only in: path is forced torequired: true.
204 No Content success still counts as the documented success response (no body needed).operations) belongs in components/schemas.
operationId stays stable once published — renaming it breaks generated client method names.components/schemas.operationId. Don't leave operations id-less or duplicate an id.{path} parameter in: path, required: true. Don't leave a templatedsegment undeclared.
tags. Don't ship untagged operations.200.$ref. Don't re-inline the same object in every operation.operationId, or the same id reused on two operations.get_user) or noun-first (userGet) operation ids./{id} in the path with no matching parameters entry, or one missing required: true.tags, so the docs render one flat, ungrouped list.200 documented — no 4xx/5xx.$ref.components/schemas keys instead of PascalCase.operationId and a summary.{path} segment: declared in: path, required: true.tag, and both a success and an error response by status code.components/schemas entry, referenced by $ref.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | verified | 7/10/2026 | +50% |
Other measured skills in the registry, with their headline benchmark lift.