¿Cuáles son las buenas prácticas para definir respuestas de error en OpenAPI?

¿Cuáles son las buenas prácticas para definir respuestas de error en OpenAPI? #

Las respuestas de error son una parte crítica de cualquier contrato de API. Un consumidor que se encuentra con un error necesita entender qué salió mal, por qué ocurrió y, idealmente, qué hacer al respecto. Sin embargo, las respuestas de error suelen ser la parte más descuidada de un documento OpenAPI: con frecuencia están sin documentar, tienen una estructura inconsistente o solo se documentan para el caso ideal. Este artículo recoge las buenas prácticas para definir respuestas de error en OpenAPI que den a los consumidores la información que necesitan para construir integraciones resilientes.

Por qué importa la documentación de errores #

Cuando las respuestas de error están mal documentadas:

  • Los desarrolladores de clientes improvisan al gestionar los errores, lo que genera código de gestión de errores frágil que se rompe cuando aparecen nuevos formatos de error.
  • Los equipos de soporte dedican más tiempo a investigar problemas de integración que serían de autoservicio si el formato de error estuviera bien documentado.
  • Los SDK y los generadores de código producen una gestión de errores incompleta porque el documento OpenAPI carece de esquemas de respuestas de error.
  • Las herramientas de gobierno de API no pueden auditar la cobertura de errores porque no hay nada que auditar.

Una documentación de errores completa en OpenAPI es una inversión en la experiencia del desarrollador de todos los que consumen la API.

Documenta todos los códigos de estado HTTP relevantes #

Cada operación de OpenAPI debería documentar todos los códigos de estado HTTP que pueda devolver de forma realista. El objeto responses usa los códigos de estado como claves:

paths:
  /users/{id}:
    get:
      summary: Get a user by ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: The user was found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        "400":
          description: Invalid user ID format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        "401":
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        "403":
          description: Insufficient permissions to access this user
          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
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        "500":
          description: Unexpected server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Un error habitual es documentar solo 200 y 404. Las operaciones deberían documentar como mínimo: 400 (solicitud incorrecta), 401 (sin autenticar), 403 (sin autorización), 404 (no encontrado, cuando proceda), 429 (límite de solicitudes superado) y 500 (error del servidor).

Usa un esquema de error coherente #

Todas las respuestas de error deberían usar el mismo esquema (o uno estructuralmente similar). Los formatos de error inconsistentes entre endpoints obligan a los consumidores a implementar una lógica de gestión de errores distinta para cada operación, un grave fallo de experiencia del desarrollador.

Esquema de error mínimo #

components:
  schemas:
    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          description: A machine-readable error code
          example: "USER_NOT_FOUND"
        message:
          type: string
          description: A human-readable description of the error
          example: "No user found with the provided ID"

Esquema de error enriquecido con detalles #

Para las API que necesitan comunicar errores de validación en varios campos:

components:
  schemas:
    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          example: "VALIDATION_ERROR"
        message:
          type: string
          example: "The request body contains invalid fields"
        details:
          type: array
          items:
            $ref: '#/components/schemas/ErrorDetail'
        requestId:
          type: string
          description: Unique identifier for this request, for support reference
          example: "req_4e8f9a2b"

    ErrorDetail:
      type: object
      required: [field, message]
      properties:
        field:
          type: string
          description: The field that caused the error
          example: "email"
        message:
          type: string
          description: Description of the validation failure
          example: "Must be a valid email address"
        code:
          type: string
          example: "INVALID_FORMAT"

Adopta RFC 9457 Problem Details #

RFC 9457 (anteriormente RFC 7807) define un formato JSON estándar para las respuestas de error de las API HTTP llamado Problem Details. Adoptarlo significa que los consumidores pueden gestionar los errores de cualquier API compatible con RFC 9457 usando el mismo modelo de error:

components:
  schemas:
    ProblemDetails:
      type: object
      properties:
        type:
          type: string
          format: uri
          description: A URI identifying the problem type
          example: "https://api.example.com/errors/user-not-found"
        title:
          type: string
          description: A short, human-readable summary of the problem type
          example: "User Not Found"
        status:
          type: integer
          description: The HTTP status code
          example: 404
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence
          example: "No user with ID 'abc123' exists"
        instance:
          type: string
          format: uri
          description: A URI identifying this specific occurrence of the problem
          example: "/users/abc123"

El URI de type es un identificador estable y enlazable del tipo de error, que idealmente apunta a documentación que explique el error y cómo resolverlo. Esto hace que Problem Details se documente a sí mismo, algo que los códigos de error numéricos opacos no consiguen.

Usa default para las respuestas de error generales #

OpenAPI admite una clave de respuesta especial default que coincide con cualquier código de estado HTTP que no figure de forma explícita. Es útil para documentar una respuesta genérica de error del servidor sin tener que enumerar todos los posibles códigos 5xx:

responses:
  "200":
    description: OK
  "404":
    description: Not found
  default:
    description: An unexpected error occurred
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/Error'

La clave default complementa a los códigos de estado explícitos; no sustituye a los específicos.

Define respuestas de error reutilizables en components #

Para las API con muchas operaciones, definir las respuestas de error una sola vez en components/responses y referenciarlas con $ref mantiene el documento sin repeticiones (DRY) y garantiza la coherencia:

components:
  responses:
    BadRequest:
      description: The request is malformed or contains invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalidId:
              summary: Invalid ID format
              value:
                code: "INVALID_PARAMETER"
                message: "The provided ID must be a UUID"

    Unauthorized:
      description: Authentication is required or the token is invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    Forbidden:
      description: The authenticated user lacks permission for this operation
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    NotFound:
      description: The requested resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    TooManyRequests:
      description: Rate limit exceeded
      headers:
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    InternalServerError:
      description: An unexpected server error occurred
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

Después, las operaciones las referencian con $ref:

responses:
  "200":
    ...
  "400":
    $ref: '#/components/responses/BadRequest'
  "401":
    $ref: '#/components/responses/Unauthorized'
  "404":
    $ref: '#/components/responses/NotFound'
  "429":
    $ref: '#/components/responses/TooManyRequests'
  default:
    $ref: '#/components/responses/InternalServerError'

Incluye ejemplos de error #

Los ejemplos en las respuestas de error ayudan a los consumidores a entender exactamente qué aspecto tiene un error en la práctica:

"404":
  description: User not found
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/Error'
      examples:
        userNotFound:
          summary: User not found
          value:
            code: "USER_NOT_FOUND"
            message: "No user found with ID 'f47ac10b'"
            requestId: "req_7g3h8k2m"

Conclusión #

Las respuestas de error bien documentadas en OpenAPI son tan importantes como la documentación de las respuestas correctas. Al definir un esquema de error coherente, adoptar RFC 9457 Problem Details, documentar todos los códigos de estado HTTP relevantes, centralizar las definiciones de respuestas de error en components/responses e incluir ejemplos concretos, los equipos de API ofrecen a los consumidores todo lo que necesitan para construir integraciones sólidas y resilientes. Una API cuyos errores están tan bien diseñados y documentados como sus flujos correctos es una API que se gana la confianza de sus consumidores.


Última actualización: 30 de abril de 2026.

Este sitio web no está afiliado a la OpenAPI Initiative.