openapi: 3.1.0
info:
  title: Train Travel API
  description: API for finding and booking train trips across Europe.
  version: 1.0.0
  contact:
    name: Train Support
    url: https://example.com/support
    email: support@example.com
  license:
    name: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
    identifier: CC-BY-NC-SA-4.0
servers:
  - url: https://api.example.com
    description: Production
security:
  - OAuth2:
      - read
tags:
  - name: Stations
    description: Find and filter train stations across Europe, including their location  and local timezone.
  - name: Trips
    description: Timetables and routes for train trips between stations, including  pricing and availability.
  - name: Bookings
    description: Create and manage bookings for train trips, including passenger  details and optional extras.
  - name: Payments
    description: |
      Pay for bookings using a card or bank account, and view payment
      status and history.

      > warn
      > Bookings usually expire within 1 hour so you'll need to make your payment before the expiry date
paths:
  /stations:
    get:
      summary: Get a list of train stations
      description: Returns a list of all train stations in the system.
      operationId: get-stations
      tags:
        - Stations
      responses:
        '200':
          description: A list of train stations
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Station'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
              example:
                data:
                  - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                    name: Berlin Hauptbahnhof
                    address: Invalidenstraße 10557 Berlin, Germany
                    country_code: DE
                    timezone: Europe/Berlin
                  - id: b2e783e1-c824-4d63-b37a-d8d698862f1d
                    name: Paris Gare du Nord
                    address: 18 Rue de Dunkerque 75010 Paris, France
                    country_code: FR
                    timezone: Europe/Paris
                links:
                  self: https://api.example.com/stations&page=2
                  next: https://api.example.com/stations?page=3
                  prev: https://api.example.com/stations?page=1
            application/xml:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        xml:
                          name: stations
                          wrapped: true
                        items:
                          $ref: '#/components/schemas/Station'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /trips:
    get:
      summary: Get available train trips
      description: Returns a list of available train trips between the specified origin and destination stations on the given date, and allows for filtering by bicycle and dog allowances.
      operationId: get-trips
      tags:
        - Trips
      parameters:
        - name: origin
          in: query
          description: The ID of the origin station
          required: true
          schema:
            type: string
            format: uuid
          example: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
        - name: destination
          in: query
          description: The ID of the destination station
          required: true
          schema:
            type: string
            format: uuid
          example: b2e783e1-c824-4d63-b37a-d8d698862f1d
        - name: date
          in: query
          description: The date and time of the trip in ISO 8601 format in origin station's timezone.
          required: true
          schema:
            type: string
            format: date-time
          example: '2024-02-01T09:00:00Z'
        - name: bicycles
          in: query
          description: Only return trips where bicycles are known to be allowed
          required: false
          schema:
            type: boolean
            default: false
        - name: dogs
          in: query
          description: Only return trips where dogs are known to be allowed
          required: false
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: A list of available train trips
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Trip'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
              example:
                data:
                  - id: ea399ba1-6d95-433f-92d1-83f67b775594
                    origin: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                    destination: b2e783e1-c824-4d63-b37a-d8d698862f1d
                    departure_time: '2024-02-01T10:00:00Z'
                    arrival_time: '2024-02-01T16:00:00Z'
                    price: 50
                    operator: Deutsche Bahn
                    bicycles_allowed: true
                    dogs_allowed: true
                  - id: 4d67459c-af07-40bb-bb12-178dbb88e09f
                    origin: b2e783e1-c824-4d63-b37a-d8d698862f1d
                    destination: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                    departure_time: '2024-02-01T12:00:00Z'
                    arrival_time: '2024-02-01T18:00:00Z'
                    price: 50
                    operator: SNCF
                    bicycles_allowed: true
                    dogs_allowed: true
                links:
                  self: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01
                  next: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01&page=2
            application/xml:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        xml:
                          name: trips
                          wrapped: true
                        items:
                          $ref: '#/components/schemas/Trip'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /bookings:
    get:
      operationId: get-bookings
      summary: List existing bookings
      description: Returns a list of all trips booking by the authenticated user.
      tags:
        - Bookings
      responses:
        '200':
          description: A list of bookings
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
              example:
                data:
                  - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                    trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                    passenger_name: John Doe
                    has_bicycle: true
                    has_dog: true
                  - id: b2e783e1-c824-4d63-b37a-d8d698862f1d
                    trip_id: b2e783e1-c824-4d63-b37a-d8d698862f1d
                    passenger_name: Jane Smith
                    has_bicycle: false
                    has_dog: false
                links:
                  self: https://api.example.com/bookings
                  next: https://api.example.com/bookings?page=2
            application/xml:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Wrapper-Collection'
                  - properties:
                      data:
                        type: array
                        xml:
                          name: bookings
                          wrapped: true
                        items:
                          $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        allOf:
                          - $ref: '#/components/schemas/Links-Self'
                          - $ref: '#/components/schemas/Links-Pagination'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    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.
      tags:
        - Bookings
      security:
        - OAuth2:
            - write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Booking'
          application/xml:
            schema:
              $ref: '#/components/schemas/Booking'
      responses:
        '201':
          description: Booking successful
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        $ref: '#/components/schemas/Links-Self'

              example:
                id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                passenger_name: John Doe
                has_bicycle: true
                has_dog: true
                links:
                  self: https://api.example.com/bookings/efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
            application/xml:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        $ref: '#/components/schemas/Links-Self'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /bookings/{bookingId}:
    parameters:
      - name: bookingId
        in: path
        required: true
        description: The ID of the booking to retrieve.
        schema:
          type: string
          format: uuid
        example: 1725ff48-ab45-4bb5-9d02-88745177dedb
    get:
      summary: Get a booking
      description: Returns the details of a specific booking.
      operationId: get-booking
      tags:
        - Bookings
      responses:
        '200':
          description: The booking details
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        $ref: '#/components/schemas/Links-Self'
              example:
                id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
                passenger_name: John Doe
                has_bicycle: true
                has_dog: true
                links:
                  self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb
            application/xml:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Booking'
                  - properties:
                      links:
                        $ref: '#/components/schemas/Links-Self'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      summary: Delete a booking
      description: Deletes a booking, cancelling the hold on the trip.
      operationId: delete-booking
      security:
        - OAuth2:
            - write
      tags:
        - Bookings
      responses:
        '204':
          description: Booking deleted
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /bookings/{bookingId}/payment:
    parameters:
      - name: bookingId
        in: path
        required: true
        description: The ID of the booking to pay for.
        schema:
          type: string
          format: uuid
        example: 1725ff48-ab45-4bb5-9d02-88745177dedb
    post:
      summary: Pay for a Booking
      description: A payment is an attempt to pay for the booking, which will confirm the booking for the user and enable them to get their tickets.
      operationId: create-booking-payment
      tags:
        - Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingPayment'
            examples:
              Card:
                summary: Card Payment
                value:
                  amount: 49.99
                  currency: gbp
                  source:
                    object: card
                    name: J. Doe
                    number: '4242424242424242'
                    cvc: 123
                    exp_month: 12
                    exp_year: 2025
                    address_line1: 123 Fake Street
                    address_line2: 4th Floor
                    address_city: London
                    address_country: gb
                    address_post_code: N12 9XX
              Bank:
                summary: Bank Account Payment
                value:
                  amount: 100.5
                  currency: gbp
                  source:
                    object: bank_account
                    name: J. Doe
                    number: '00012345'
                    sort_code: '000123'
                    account_type: individual
                    bank_name: Starling Bank
                    country: gb
      responses:
        '200':
          description: Payment successful
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/BookingPayment'
                  - properties:
                      links:
                        $ref: '#/components/schemas/Links-Booking'
              examples:
                Card:
                  summary: Card Payment
                  value:
                    id: 2e3b4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
                    amount: 49.99
                    currency: gbp
                    source:
                      object: card
                      name: J. Doe
                      number: '************4242'
                      cvc: 123
                      exp_month: 12
                      exp_year: 2025
                      address_country: gb
                      address_post_code: N12 9XX
                    status: succeeded
                    links:
                      booking: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb/payment
                Bank:
                  summary: Bank Account Payment
                  value:
                    id: 2e3b4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a
                    amount: 100.5
                    currency: gbp
                    source:
                      object: bank_account
                      name: J. Doe
                      account_type: individual
                      number: '*********2345'
                      sort_code: '000123'
                      bank_name: Starling Bank
                      country: gb
                    status: succeeded
                    links:
                      booking: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
webhooks:
  newBooking:
    post:
      operationId: new-booking
      summary: New Booking
      description: |
        Subscribe to new bookings being created, to update integrations for your users.  Related data is available via the links provided in the request.
      tags:
        - Bookings
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/Booking'
                - properties:
                    links:
                      allOf:
                        - $ref: '#/components/schemas/Links-Self'
                        - $ref: '#/components/schemas/Links-Pagination'
            example:
              id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
              trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
              passenger_name: John Doe
              has_bicycle: true
              has_dog: true
              links:
                self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb
      responses:
        '200':
          description: Return a 200 status to indicate that the data was received successfully.
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      description: OAuth 2.0 authorization code following RFC8725 best practices.
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Read access
            write: Write access
  schemas:
    Station:
      type: object
      xml:
        name: station
      required:
        - id
        - name
        - address
        - country_code
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the station.
          examples:
            - efdbb9d1-02c2-4bc3-afb7-6788d8782b1e
            - b2e783e1-c824-4d63-b37a-d8d698862f1d
        name:
          type: string
          description: The name of the station
          examples:
            - Berlin Hauptbahnhof
            - Paris Gare du Nord
        address:
          type: string
          description: The address of the station.
          examples:
            - Invalidenstraße 10557 Berlin, Germany
            - 18 Rue de Dunkerque 75010 Paris, France
        country_code:
          type: string
          description: The country code of the station.
          format: iso-country-code
          examples:
            - DE
            - FR
        timezone:
          type: string
          description: The timezone of the station in the [IANA Time Zone Database format](https://www.iana.org/time-zones).
          examples:
            - Europe/Berlin
            - Europe/Paris
        testfield:
            patter: "^[^:<>;#/\"\\*\\|\\?\\\\]*$"
            type: string
    
    Links-Self:
      type: object
      properties:
        self:
          type: string
          format: uri
    Links-Pagination:
      type: object
      properties:
        next:
          type: string
          format: uri
        prev:
          type: string
          format: uri
    Problem:
      xml:
        name: problem
        namespace: urn:ietf:rfc:7807
      properties:
        type:
          type: string
          description: A URI reference that identifies the problem type
          example: https://example.com/probs/out-of-credit
        title:
          type: string
          description: A short, human-readable summary of the problem type
          example: You do not have enough credit.
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence of the problem
          example: Your current balance is 30, but that costs 50.
        instance:
          type: string
          description: A URI reference that identifies the specific occurrence of the problem
          example: /account/12345/msgs/abc
        status:
          type: integer
          description: The HTTP status code
          example: 400
    Trip:
      type: object
      xml:
        name: trip
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the trip
          examples:
            - 4f4e4e1-c824-4d63-b37a-d8d698862f1d
        origin:
          type: string
          description: The starting station of the trip
          examples:
            - Berlin Hauptbahnhof
            - Paris Gare du Nord
        destination:
          type: string
          description: The destination station of the trip
          examples:
            - Paris Gare du Nord
            - Berlin Hauptbahnhof
        departure_time:
          type: string
          format: date-time
          description: The date and time when the trip departs
          examples:
            - '2024-02-01T10:00:00Z'
        arrival_time:
          type: string
          format: date-time
          description: The date and time when the trip arrives
          examples:
            - '2024-02-01T16:00:00Z'
        operator:
          type: string
          description: The name of the operator of the trip
          examples:
            - Deutsche Bahn
            - SNCF
        price:
          type: number
          description: The cost of the trip
          examples:
            - 50
        bicycles_allowed:
          type: boolean
          description: Indicates whether bicycles are allowed on the trip
        dogs_allowed:
          type: boolean
          description: Indicates whether dogs are allowed on the trip
    Booking:
      type: object
      xml:
        name: booking
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the booking
          readOnly: true
          examples:
            - 3f3e3e1-c824-4d63-b37a-d8d698862f1d
        trip_id:
          type: string
          format: uuid
          description: Identifier of the booked trip
          examples:
            - 4f4e4e1-c824-4d63-b37a-d8d698862f1d
        passenger_name:
          type: string
          description: Name of the passenger
          examples:
            - John Doe
        has_bicycle:
          type: boolean
          description: Indicates whether the passenger has a bicycle.
        has_dog:
          type: boolean
          description: Indicates whether the passenger has a dog.
    Wrapper-Collection:
      description: This is a generic request/response wrapper which contains both data and links which serve as hypermedia controls (HATEOAS).
      type: object
      properties:
        data:
          description: The wrapper for a collection is an array of objects.
          type: array
          items:
            type: object
        links:
          description: A set of hypermedia links which serve as controls for the client.
          type: object
          readOnly: true
      xml:
        name: data
    BookingPayment:
      type: object
      properties:
        id:
          description: Unique identifier for the payment. This will be a unique identifier for the payment, and is used to reference the payment in other objects.
          type: string
          format: uuid
          readOnly: true
        amount:
          description: Amount intended to be collected by this payment. A positive decimal figure describing the amount to be collected.
          type: number
          exclusiveMinimum: 0
          examples:
            - 49.99
        currency:
          description: Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
          type: string
          enum:
            - bam
            - bgn
            - chf
            - eur
            - gbp
            - nok
            - sek
            - try
        source:
          unevaluatedProperties: false
          description: The payment source to take the payment from. This can be a card or a bank account. Some of these properties will be hidden on read to protect PII leaking.
          anyOf:
            - title: Card
              description: A card (debit or credit) to take payment from.
              properties:
                object:
                  type: string
                  const: card
                name:
                  type: string
                  description: Cardholder's full name as it appears on the card.
                  examples:
                    - Francis Bourgeois
                number:
                  type: string
                  description: The card number, as a string without any separators. On read all but the last four digits will be masked for security.
                  examples:
                    - '4242424242424242'
                cvc:
                  type: integer
                  description: Card security code, 3 or 4 digits usually found on the back of the card.
                  minLength: 3
                  maxLength: 4
                  writeOnly: true

                  example: 123
                exp_month:
                  type: integer
                  format: int64
                  description: Two-digit number representing the card's expiration month.
                  examples:
                    - 12
                exp_year:
                  type: integer
                  format: int64
                  description: Four-digit number representing the card's expiration year.
                  examples:
                    - 2025
                address_line1:
                  type: string
                  writeOnly: true
                address_line2:
                  type: string
                  writeOnly: true
                address_city:
                  type: string
                address_country:
                  type: string
                address_post_code:
                  type: string
              required:
                - name
                - number
                - cvc
                - exp_month
                - exp_year
                - address_country
            - title: Bank Account
              description: A bank account to take payment from. Must be able to make payments in the currency specified in the payment.
              type: object
              properties:
                object:
                  const: bank_account
                  type: string
                name:
                  type: string
                number:
                  type: string
                  description: The account number for the bank account, in string form. Must be a current account.
                sort_code:
                  type: string
                  description: The sort code for the bank account, in string form. Must be a six-digit number.
                account_type:
                  enum:
                    - individual
                    - company
                  type: string
                  description: The type of entity that holds the account. This can be either `individual` or `company`.
                bank_name:
                  type: string
                  description: The name of the bank associated with the routing number.
                  examples:
                    - Starling Bank
                country:
                  type: string
                  description: Two-letter country code (ISO 3166-1 alpha-2).
              required:
                - name
                - number
                - account_type
                - bank_name
                - country
        status:
          description: The status of the payment, one of `pending`, `succeeded`, or `failed`.
          type: string
          enum:
            - pending
            - succeeded
            - failed
          readOnly: true
    Links-Booking:
      type: object
      properties:
        booking:
          type: string
          format: uri
          examples:
            - https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb
  headers:
    RateLimit:
      description: |
        The RateLimit header is communicate quota policies, and contains a `limit` to
        conveys the expiring limit, `remaining` to convey the remaining quota units,
        and `reset` to convey the time window reset time.
      schema:
        type: string
        examples:
          - limit=10, remaining=0, reset=10

    Retry-After:
      description: |
        The Retry-After header indicates how long the user agent should wait before making a follow-up request. 
        The value is in seconds and can be an integer or a date in the future. 
        If the value is an integer, it indicates the number of seconds to wait. 
        If the value is a date, it indicates the time at which the user agent should make a follow-up request.
      schema:
        type: string
      examples:
        integer:
          value: '120'
          summary: Retry after 120 seconds
        date:
          value: 'Fri, 31 Dec 2021 23:59:59 GMT'
          summary: Retry after the specified date

  responses:
    BadRequest:
      description: Bad Request
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/bad-request
            title: Bad Request
            status: 400
            detail: The request is invalid or missing required parameters.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/bad-request
            title: Bad Request
            status: 400
            detail: The request is invalid or missing required parameters.

    Conflict:
      description: Conflict
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/conflict
            title: Conflict
            status: 409
            detail: There is a conflict with an existing resource.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/conflict
            title: Conflict
            status: 409
            detail: There is a conflict with an existing resource.

    Forbidden:
      description: Forbidden
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/forbidden
            title: Forbidden
            status: 403
            detail: Access is forbidden for the provided credentials.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/forbidden
            title: Forbidden
            status: 403
            detail: Access is forbidden for the provided credentials.

    InternalServerError:
      description: Internal Server Error
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/internal-server-error
            title: Internal Server Error
            status: 500
            detail: An unexpected error occurred.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/internal-server-error
            title: Internal Server Error
            status: 500
            detail: An unexpected error occurred.

    NotFound:
      description: Not Found
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/not-found
            title: Not Found
            status: 404
            detail: The requested resource was not found.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/not-found
            title: Not Found
            status: 404
            detail: The requested resource was not found.

    TooManyRequests:
      description: Too Many Requests
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/too-many-requests
            title: Too Many Requests
            status: 429
            detail: You have exceeded the rate limit.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/too-many-requests
            title: Too Many Requests
            status: 429
            detail: You have exceeded the rate limit.

    Unauthorized:
      description: Unauthorized
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/unauthorized
            title: Unauthorized
            status: 401
            detail: You do not have the necessary permissions.
        application/problem+xml:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://example.com/errors/unauthorized
            title: Unauthorized
            status: 401
            detail: You do not have the necessary permissions.