Install
$ agentstack add skill-speakeasy-api-skills-writing-openapi-specs ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Writing OpenAPI Specs
Reference for OpenAPI best practices and conventions. This skill provides guidance on taste, conventions, and grey areas not covered by the OpenAPI specification itself.
When to Use This Skill
- Writing a new OpenAPI specification
- Improving operation naming and organization
- Expressing complex data types (enums, polymorphism, nullable)
- Handling file uploads, streaming, or server-sent events
- Making specs more code-gen friendly
- Understanding reusability patterns (components vs inline)
Core Principles
Naming Conventions
Operation IDs: Use lowercase with underscores, following resource_action pattern:
# Good
operationId: users_list
operationId: users_get
operationId: users_create
# Avoid
operationId: GetApiV1Users # Auto-generated, not semantic
Component Names: Use PascalCase for schemas, parameters, and other reusable components:
components:
schemas:
UserProfile: # PascalCase
OrderHistory: # PascalCase
parameters:
PageLimit: # PascalCase
Tags: Use lowercase with hyphens for machine-friendly tags:
tags:
- name: user-management
description: Operations for managing users
- name: order-processing
description: Operations for processing orders
For more details, see [reference/operations.md](reference/operations.md) and [reference/components.md](reference/components.md).
Documentation Standards
Use CommonMark: All description fields support CommonMark syntax for rich formatting:
description: |
Retrieves a user by ID.
## Authorization
Requires `users:read` scope.
## Rate Limits
- 100 requests per minute per API key
- 1000 requests per hour per IP
Be Specific: Provide actionable information, not generic descriptions:
# Good
description: Returns a paginated list of active users, ordered by creation date (newest first)
# Avoid
description: Gets users
Use examples over example: The plural examples field provides better SDK generation:
# Good
examples:
basic_user:
value:
id: 123
name: "John Doe"
admin_user:
value:
id: 456
name: "Jane Admin"
role: admin
# Avoid single example
example:
id: 123
name: "John Doe"
For more details, see [reference/examples.md](reference/examples.md).
Reusability
Create components for:
- Schemas used in multiple operations
- Common parameters (pagination, filtering)
- Common responses (errors, success patterns)
- Security schemes
Keep inline for:
- Operation-specific request bodies
- Unique response shapes
- One-off parameters
# Reusable schema
components:
schemas:
User:
type: object
properties:
id: {type: integer}
name: {type: string}
# Reference it
paths:
/users/{id}:
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/User'
For more details, see [reference/components.md](reference/components.md).
Complex Patterns Quick Reference
These patterns are commonly challenging. Brief examples below with links to detailed guidance.
Enums
Use string enums with clear, semantic values:
type: string
enum:
- pending
- approved
- rejected
- cancelled
Avoid:
- Numeric strings ("0", "1", "2")
- Generic values ("value1", "value2")
- Unclear abbreviations ("pnd", "appr")
See [reference/schemas.md#enums](reference/schemas.md) for more.
Polymorphism (oneOf/allOf/anyOf)
oneOf: Value matches exactly one schema (type discrimination)
PaymentMethod:
oneOf:
- $ref: '#/components/schemas/CreditCard'
- $ref: '#/components/schemas/BankAccount'
- $ref: '#/components/schemas/PayPal'
discriminator:
propertyName: type
mapping:
credit_card: '#/components/schemas/CreditCard'
bank_account: '#/components/schemas/BankAccount'
paypal: '#/components/schemas/PayPal'
allOf: Value matches all schemas (composition/inheritance)
AdminUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
permissions:
type: array
items: {type: string}
anyOf: Value matches one or more schemas (flexible union)
SearchFilter:
anyOf:
- $ref: '#/components/schemas/TextFilter'
- $ref: '#/components/schemas/DateFilter'
- $ref: '#/components/schemas/NumericFilter'
See [reference/schemas.md#polymorphism](reference/schemas.md) for detailed guidance.
Discriminators
Use discriminators with oneOf for efficient type identification:
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'
Dog:
type: object
required: [petType, bark]
properties:
petType:
type: string
enum: [dog]
bark:
type: string
Cat:
type: object
required: [petType, meow]
properties:
petType:
type: string
enum: [cat]
meow:
type: string
See [reference/schemas.md#discriminators](reference/schemas.md) for more.
Nullable Types
Handle null values differently based on OpenAPI version:
OpenAPI 3.1 (JSON Schema 2020-12 compliant):
type: [string, "null"]
# or
type: string
nullable: true # Still supported for compatibility
OpenAPI 3.0:
type: string
nullable: true
For optional fields, use required array:
type: object
properties:
name: {type: string} # Can be omitted
email: {type: string} # Can be omitted
required: [name] # email is optional
See [reference/schemas.md#nullable](reference/schemas.md) for more.
File Uploads
Use multipart/form-data for file uploads:
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
metadata:
type: object
properties:
description: {type: string}
tags:
type: array
items: {type: string}
required: [file]
For base64-encoded files in JSON:
requestBody:
content:
application/json:
schema:
type: object
properties:
filename: {type: string}
content:
type: string
format: byte # base64-encoded
See [reference/request-bodies.md#file-uploads](reference/request-bodies.md) for more.
Server-Sent Events (SSE)
Express streaming responses with text/event-stream:
responses:
'200':
description: Stream of events
content:
text/event-stream:
schema:
type: string
description: |
Server-sent events stream. Each event follows the format:
```
event: message
data: {"type": "update", "content": "..."}
```
examples:
notification_stream:
value: |
event: message
data: {"type": "notification", "message": "New order received"}
event: message
data: {"type": "notification", "message": "Order processing complete"}
See [reference/responses.md#streaming](reference/responses.md) for more patterns.
Field Reference
Detailed guidance for each major OpenAPI field:
- Operations: Operation IDs, methods, tags, deprecation → [reference/operations.md](reference/operations.md)
- Schemas: Data types, polymorphism, enums, nullable → [reference/schemas.md](reference/schemas.md)
- Parameters: Path, query, header, cookie parameters → [reference/parameters.md](reference/parameters.md)
- Request Bodies: Content types, file uploads, encoding → [reference/request-bodies.md](reference/request-bodies.md)
- Responses: Status codes, streaming, error patterns → [reference/responses.md](reference/responses.md)
- Components: Reusable definitions, organization → [reference/components.md](reference/components.md)
- Security: Authentication schemes, scopes, granular control → [reference/security.md](reference/security.md)
- Examples: Single and multiple examples, placement → [reference/examples.md](reference/examples.md)
SDK Generation Considerations
When writing specs for SDK generation:
- Always define
operationId: Required for meaningful method names - Provide rich examples: Helps generate better documentation and tests
- Be explicit about required fields: Affects SDK method signatures
- Use discriminators with oneOf: Generates type-safe unions
- Document error responses: Generates better error handling code
Example SDK-friendly operation:
paths:
/users:
get:
operationId: users_list
summary: List all users
description: Returns a paginated list of users
parameters:
- name: limit
in: query
schema: {type: integer, default: 20}
- name: offset
in: query
schema: {type: integer, default: 0}
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
required: [data, pagination]
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/PaginationInfo'
examples:
success:
value:
data: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}]
pagination: {total: 100, limit: 20, offset: 0}
This generates: sdk.users.list({limit: 20, offset: 0})
Common Pitfalls
Don't:
- Use generic descriptions like "Gets data" or "Returns object"
- Mix naming conventions (pick one style and stick to it)
- Forget
operationId(causes auto-generated names) - Use
examplewhen you meanexamples(plural is better) - Make everything required (be thoughtful about optional fields)
- Inline everything (use components for reusability)
- Reference everything (inline simple one-off schemas)
- Forget to document error responses
- Use magic numbers without explanation
- Omit content types (be explicit)
Do:
- Provide actionable, specific descriptions
- Use consistent naming patterns throughout
- Define clear
operationIdfor every operation - Use
examples(plural) with named examples - Carefully consider required vs optional fields
- Balance reusability with clarity
- Document all expected responses (success and errors)
- Explain constraints and validation rules
- Be explicit about content types and formats
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: speakeasy-api
- Source: speakeasy-api/skills
- License: Apache-2.0
- Homepage: https://www.speakeasy.com/docs
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.