What are the best practices for naming conventions in OpenAPI documents? #
Naming is one of the most consequential design decisions in an OpenAPI document. Names appear in generated documentation, generated SDKs and clients, API explorer UIs, and internal references throughout the document. Poor naming creates confusion, makes generated code awkward, and signals inconsistency to API consumers. Good naming is consistent, predictable, and meaningful. This article covers best practices for every major naming surface in an OpenAPI document.
Path Naming #
API paths are the most visible naming surface — they appear in every API call and in all documentation.
Use Lowercase, Hyphen-Separated Words #
# Good
/user-profiles/{userId}
/payment-methods/{methodId}
# Avoid
/UserProfiles/{userId}
/payment_methods/{methodId}
Lowercase hyphen-separated paths (kebab-case) are the most widely adopted convention and are compatible with all HTTP frameworks and clients. Mixed case paths create unnecessary complexity since HTTP paths are technically case-sensitive but users often expect case-insensitivity.
Use Nouns for Resources, Not Verbs #
HTTP methods express the action; paths express the resource:
# Good
GET /orders # List orders
POST /orders # Create an order
GET /orders/{id} # Get a specific order
DELETE /orders/{id} # Delete an order
# Avoid
GET /getOrders
POST /createOrder
DELETE /deleteOrder/{id}
The resource name should be a noun (or noun phrase) that represents the concept, not the operation being performed on it.
Use Plural Nouns for Collections #
Collections of resources should use plural nouns:
# Good
/users
/products
/payment-methods
# Avoid
/user
/product
/payment-method
Plural nouns make it clear that a collection is being addressed and create a consistent pattern: GET /users returns a list; GET /users/{id} returns one item.
Path Parameters #
Path parameter names should use camelCase and describe exactly what they identify:
# Good
/users/{userId}
/orders/{orderId}/items/{itemId}
# Avoid
/users/{id} # 'id' is ambiguous in nested contexts
/orders/{order_id} # snake_case in path params is inconsistent
/users/{user} # doesn't communicate it's an ID
Using {userId} rather than {id} is especially important for nested resources where multiple {id} parameters would be ambiguous.
Operation IDs #
The operationId field uniquely identifies each operation in the document. It has direct impact on generated SDK method names:
paths:
/users:
get:
operationId: listUsers # Good: verb + noun
post:
operationId: createUser # Good: verb + noun
/users/{userId}:
get:
operationId: getUser # Good
put:
operationId: updateUser # Good
delete:
operationId: deleteUser # Good
/users/{userId}/addresses:
get:
operationId: listUserAddresses # Good: includes parent resource context
post:
operationId: createUserAddress # Good
Operation ID Rules #
- Use camelCase
- Always use a verb-noun pattern:
getUser,listOrders,createPaymentMethod,deleteAccount - Never reuse an operation ID (they must be unique across the document)
- Include parent resource context for nested operations:
listUserOrders, not justlistOrders, when under/users/{userId}/orders - Avoid abbreviations:
listApplicationsnotlistApps
Operation IDs that follow these conventions produce generated SDKs with readable, predictable method names: client.users.list(), client.users.create(), client.users.get(userId).
Schema Names #
Schema names appear as type names in generated code, making them one of the most developer-facing naming surfaces.
Use PascalCase for Schema Names #
components:
schemas:
User: ... # Good
UserProfile: ... # Good
PaymentMethod: ... # Good
CreateUserRequest: ... # Good
UserListResponse: ... # Good
user: ... # Bad: lowercase
user_profile: ... # Bad: snake_case
PAYMENT_METHOD: ... # Bad: screaming snake case
PascalCase schema names produce idiomatic class and type names in most generated languages: User in TypeScript, User in Python, User in Java and Go.
Use Descriptive, Self-Explanatory Names #
Schema names should describe what they represent without requiring documentation:
# Good: clear purpose and context
UserProfile
CreateOrderRequest
OrderListResponse
PaymentMethodSummary
AddressDetail
ApiError
# Avoid: vague or context-free
Data
Object
Info
Response
Input
Separate Request and Response Schemas When They Differ #
When the shape of a resource differs between input and output (e.g., id and createdAt are server-generated and should not be in request bodies), use separate schemas:
components:
schemas:
CreateUserRequest:
type: object
required: [email, name]
properties:
email:
type: string
name:
type: string
User:
type: object
properties:
id:
type: string
email:
type: string
name:
type: string
createdAt:
type: string
format: date-time
Reusing the same schema for both input and output leads to schemas with optional fields that are actually required on output, causing confusion in generated code.
Parameter Names #
Query, header, and cookie parameter names should follow the conventions of their location:
- Query parameters: camelCase (
pageSize,sortBy,filterStatus) - Path parameters: camelCase (
userId,orderId) - Request headers: HTTP-conventional capitalization (
Authorization,X-Request-Id,X-Api-Key)
Avoid using different conventions for the same logical parameter across different endpoints (e.g., page_size in one endpoint and pageSize in another).
Tag Names #
Tags organize operations into groups in documentation and generated code. Tag names should be:
- Title case:
User Management,Payment Methods,Orders - Or single PascalCase words:
Users,Payments,Orders - Consistent across all operations that share a logical grouping
Use the tags section at the document root to provide descriptions for each tag:
tags:
- name: Users
description: Operations for managing user accounts and profiles
- name: Orders
description: Creating, retrieving, and managing customer orders
- name: PaymentMethods
description: Managing saved payment methods for customers
Component Names #
All component names (schemas, parameters, responses, requestBodies, headers, examples, securitySchemes) should use PascalCase and be descriptive:
components:
parameters:
PageSizeParam: ...
PageCursorParam: ...
UserIdParam: ...
responses:
BadRequestResponse: ...
UnauthorizedResponse: ...
NotFoundResponse: ...
securitySchemes:
BearerAuth: ...
ApiKeyAuth: ...
Enforcing Naming Conventions with Spectral #
Spectral can automate naming convention enforcement:
rules:
operation-id-camel-case:
description: operationId must be camelCase
given: "$.paths[*][*].operationId"
severity: error
then:
function: pattern
functionOptions:
match: "^[a-z][a-zA-Z0-9]*$"
schema-names-pascal-case:
description: Schema names must be PascalCase
given: "$.components.schemas"
severity: error
then:
function: schema
functionOptions:
schema:
type: object
patternProperties:
"^[A-Z][a-zA-Z0-9]*$": {}
additionalProperties: false
Conclusion #
Consistent, well-chosen naming throughout an OpenAPI document is a sign of a mature, consumer-focused API design process. Paths, parameters, operation IDs, schema names, and component names all have downstream effects on documentation readability, generated SDK quality, and developer onboarding speed. Establishing naming conventions early, documenting them in a style guide, and enforcing them automatically with Spectral ensures that the naming quality of the API remains high as it evolves and as the team grows.
Last updated on April 30, 2026.