Skip to content

OpenAPI Responses — Defining Status Codes and Response Bodies

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about OpenAPI Responses. We cover key concepts, practical examples, and best practices to help you master this topic.

OpenAPI responses define what an API returns for each HTTP status code, including response bodies with content types and schemas, headers, and links to related operations.

In this tutorial, you will learn how to define complete response objects in OpenAPI, handle success and error responses, create reusable response definitions, and document response headers and examples.

What You'll Learn

You will learn how to define responses for each status code, structure response bodies with schemas, create reusable error responses, document response headers, and provide meaningful response examples.

Why It Matters

Response definitions are what clients use to parse and handle API output. Incomplete response documentation forces developers to guess the response format, leading to Parsing errors and runtime exceptions.

Real-World Use

DodaTech defines standardized error responses as reusable components. Every API service uses the same Error response schema with consistent fields, making client error handling identical across all services.

flowchart LR
  A[API Operation] --> B[Success Response]
  A --> C[Error Response]
  B --> D[Schema]
  B --> E[Headers]
  C --> F[Error Codes]
  C --> G[Error Details]
  A:::current
  classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px

Basic Response Definition

Every operation must define at least one response.

paths:
  /users:
    get:
      summary: List all users
      operationId: listUsers
      responses:
        "200":
          description: Successful response with user list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"

The response key is the HTTP status code as a string. The description is required for every response.

Success Responses by Status Code

Different HTTP methods use different success codes.

paths:
  /users:
    get:
      summary: List users
      responses:
        "200":
          description: Users retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
    post:
      summary: Create user
      responses:
        "201":
          description: User created successfully
          headers:
            Location:
              description: URL of the created user
              schema:
                type: string
                format: uri
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
  /users/{userId}:
    delete:
      summary: Delete user
      responses:
        "204":
          description: User deleted successfully

200 OK for successful reads and updates. 201 Created for successful resource creation. 204 No Content for successful deletions with no response body.

Error Responses

Document all possible error responses.

paths:
  /users/{userId}:
    get:
      summary: Get user by ID
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: User found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "401":
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: Insufficient permissions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: User not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer

Reusable Error Responses

Define common error responses in components.

components:
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Authentication failed or not provided
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    ValidationError:
      description: Request validation failed
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ValidationError"
    RateLimited:
      description: Too many requests
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
      headers:
        Retry-After:
          schema:
            type: integer
    InternalError:
      description: Unexpected server error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"

Using reusable responses:

paths:
  /users/{userId}:
    get:
      responses:
        "200":
          description: User found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

Response Headers

Some information belongs in response headers rather than the body.

paths:
  /users:
    get:
      summary: List users with pagination
      responses:
        "200":
          description: Paginated user list
          headers:
            X-Total-Count:
              description: Total number of users
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests remaining in current window
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/User"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

Response Examples

Provide examples for different response scenarios.

paths:
  /users/{userId}:
    get:
      responses:
        "200":
          description: User found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
              examples:
                adminUser:
                  summary: Admin user response
                  value:
                    id: 1
                    name: "Alice Johnson"
                    email: "alice@dodatech.com"
                    role: "admin"
                    createdAt: "2026-01-15T10:30:00Z"
                memberUser:
                  summary: Regular member response
                  value:
                    id: 42
                    name: "Bob Smith"
                    email: "bob@example.com"
                    role: "member"
                    createdAt: "2026-03-20T14:00:00Z"

Common Mistakes

  1. Missing error responses — Documenting only the 200 response. Every endpoint needs documentation for 400, 401, 403, 404, 429, and 500 errors.

  2. No description on responses — Omitting the description field. Every response requires a human-readable description explaining what it means.

  3. Inconsistent error schema — Using different error formats across endpoints. Define one Error schema and use it everywhere for consistency.

  4. No examples for error responses — Showing only success examples. Developers need to see what error responses look like to handle them properly.

  5. Missing 204 for delete — Defining a response body for DELETE operations. DELETE returns 204 with no body unless returning the deleted resource.

Practice Questions

  1. What response status code should a POST endpoint return for success?
  2. How do you define reusable error responses in components?
  3. What is the purpose of response headers in API documentation?
  4. Why should you provide multiple response examples?
  5. What is the minimum requirement for every response definition?

Challenge

Define a complete response set for a payment API. Include responses for successful payment (200 with receipt data), insufficient funds (402), payment method declined (402 with specific error), pending verification (202 with polling URL), and Webhook confirmation (204). Include headers for idempotency keys and rate limits.

FAQ

Can an operation have multiple success responses?

Yes. For example, a POST endpoint might return 201 for synchronous creation and 202 for asynchronous processing. Document both with examples.

What is the default response and when should I use it?

The default response matches any status code not explicitly defined. It is useful for catching undocumented error codes. Always define explicit responses when possible.

How do I document response headers?

Use the headers field under each response. Headers are key-value pairs with a name, schema, and description. Common headers include pagination counts and rate limit info.

Should I document 500 errors?

Yes. Document 500 errors even though they should not happen. Include the Error schema so clients can parse the response when things go wrong.

How detailed should response descriptions be?

Detailed enough for a developer to understand the response without guessing. Include the meaning of the status code, the conditions under which it is returned, and what the client should do next.

Mini Project

Create a complete response library for a file storage API. Define schemas for successful responses (file uploaded, file listed, file downloaded, file deleted, file moved), error responses (not found, permission denied, quota exceeded, virus detected, rate limited), and reusable response components for common status codes. Include examples for each.

What's Next

In the next lesson, you will learn how to define security schemes in OpenAPI, including API keys, HTTP authentication, OAuth2, and Openid Connect.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro