Paths and Operations

By Phil Sturgeon
Last update on July 04, 2025

OpenAPI has the concept of “paths” and “operations”, which is two parts of what people would think of as an “endpoint”. The path covers the URL and the operation covers the rest of it.

Here are a list of paths in the Train Travel API example.

paths:
  /stations:
  /trips:
  /bookings:
  /bookings/{bookingId}:
  /bookings/{bookingId}/payment:

The path defines the relative path of the API endpoint from wherever the server URL ends, which in this example is https://api.example.com, which together describe full URLs like this:

Paths can store variables, a little bit like the concept of server variables, using curly braces {} as a placeholder for a parameter which will be defined within the operation.

Defining Paths #

Each path can then define one or more operations, using HTTP methods like get, post, put, patch, or delete as a key and the operation as an object inside that.

  /bookings:
    get:
      operationId: get-bookings
      summary: List existing bookings
      description: Returns a list of all trip bookings by the authenticated user.
      responses:
        '200':
          description: A list of bookings
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Booking'

    post:
      operationId: create-booking
      summary: Create a booking
      description: A booking is a temporary hold on a trip. It is not confirmed until the payment is processed.
      security:
        - OAuth2:
            - write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Booking'
      responses:
        '201':
          description: Booking successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'

HTTP Methods #

In OpenAPI v3.1 only the following methods were allowed:

OpenAPI v3.2 expanded this list to allow:

Anything that you are using as a HTTP method could be used in an operation in capitals, so you could use the following examples:

Tempting as it is to use those old WebDAV methods, it’s probably not a great idea, but the fact that OpenAPI v3.2 lets you document any HTTP method you like is certainly an upgrade on previous versions.

Operations #

Each operation should have an operationId which is really useful for all sorts of automated tooling, and a summary which is more human-readable and helps the operation show up nicely in documentation tools.

The description can then be as long and complex as you want, using CommonMark (standardized Markdown) and multi-line YAML syntax to place all the context which cannot be picked up from just looking at variable names.

Any HTTP request which has a body (e.g.: POST, PUT, PATCH, QUERY) can define a requestBody, which can be marked as required or not. Each request can have multiple content types, supporting JSON, XML, CSV, images, whatever you need to define.

A common example would be supporting XML and JSON, but is really helpful for APIs which support image uploads being supported simultaneously via a direct Content-Type: image/* upload, whilst also supporting JSON sending the URL (e.g.: "image_url": "http://..."). It’s also handy for “import spreadsheet” type functionality.

paths:
  /bookings:
    post:
      summary: Create a new booking
      operationId: create-booking
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Booking'
          text/csv:
            schema:
              type: string
            example: |
              departureTime,arrivalTime,operator,price
              2023-04-01T10:00:00Z,2023-04-01T15:00:00Z,TrainCo,59.99
      responses:
        '200':
          description: Booking created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
            text/csv:
              schema:
                type: string
              example: |
                bookingId,departureTime,arrivalTime,operator,price
                123,2023-04-01T10:00:00Z,2023-04-01T15:00:00Z,TrainCo,59.99

The responses are then broken down by status code, and again all the responses can have multiple content types. Then the content can be further described by a schema, and an example (or examples).

For both request and response, schema is optional, but is massively helpful and worth putting in the work to define, because this is where all of the HTTP body information exists, which can contain validation rules, potential values, examples, and useful context like “why” and “how” instead of just “what”.

Parameters (Path, Query, Header, and Cookie)