What are the best practices for naming conventions in OpenAPI documents?

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 just listOrders, when under /users/{userId}/orders
  • Avoid abbreviations: listApplications not listApps

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.

This website is not affiliated with the OpenAPI Initiative.