writing-openapi-specs
Reference guide for OpenAPI specification best practices, naming conventions, and expressing complex REST API patterns like polymorphism, enums, file uploads, and server-sent events. Use when writing or improving OpenAPI specs to ensure they follow established conventions and generate quality SDKs.
Works with
---
name: writing-openapi-specs
description: Reference guide for OpenAPI specification best practices, naming conventions, and expressing complex REST API patterns like polymorphism, enums, file uploads, and server-sent events. Use when writing or improving OpenAPI specs to ensure they follow established conventions and generate quality SDKs.
license: Apache-2.0
---
# 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:
```yaml
# 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:
```yaml
components:
schemas:
UserProfile: # PascalCase
OrderHistory: # PascalCase
parameters:
PageLimit: # PascalCase
```
**Tags**: Use lowercase with hyphens for machine-friendly tags:
```yaml
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:
```yaml
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:
```yaml
# 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:
```yaml
# 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
```yaml
# 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:
```yaml
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)
```yaml
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)
```yaml
AdminUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
permissions:
type: array
items: {type: string}
```
**anyOf**: Value matches one or more schemas (flexible union)
```yaml
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:
```yaml
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):
```yaml
type: [string, "null"]
# or
type: string
nullable: true # Still supported for compatibility
```
**OpenAPI 3.0**:
```yaml
type: string
nullable: true
```
For optional fields, use `required` array:
```yaml
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:
```yaml
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:
```yaml
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`:
```yaml
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:
1. **Always define `operationId`**: Required for meaningful method names
2. **Provide rich examples**: Helps generate better documentation and tests
3. **Be explicit about required fields**: Affects SDK method signatures
4. **Use discriminators with oneOf**: Generates type-safe unions
5. **Document error responses**: Generates better error handling code
Example SDK-friendly operation:
```yaml
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 `example` when you mean `examples` (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 `operationId` for 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 formatsMore API Design skills
lark-event
larksuite/cli
Lark/Feishu real-time event listening / subscribing / consuming: stream events as NDJSON via `lark-cli event consume <EventKey>` (covers IM messages/reactions/chat changes, Approval status changes, Task updates, VC meeting started/joined/ended, Minutes generated, Whiteboard updated, etc.). Use for Lark bots, real-time message processing, long-running subscribers, streaming webhook/push handlers. Supports `--max-events` / `--timeout` bounded runs and a stderr ready-marker contract — designed for AI agents running as subprocesses.
lark-contact
larksuite/cli
飞书 / Lark 通讯录:按姓名 / 邮箱解析成 open_id,或按 open_id 反查姓名 / 部门 / 邮箱 / 联系方式 / 个人状态 / 签名,以及按关键词搜索当前用户可见的机器人 / 智能体(agent)。当用户提到一个名字要下一步发消息 / 排日程,或拿到 open_id 想查具体信息时使用。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。
lark-openapi-explorer
larksuite/cli
飞书/Lark 原生 OpenAPI 探索:从官方文档库中挖掘未经 CLI 封装的原生 OpenAPI 接口。当用户的需求无法被现有 lark-* skill 或 lark-cli 已注册命令满足,需要查找并调用原生飞书 OpenAPI 时使用。

