---
openapi: 3.0.4
info:
  title: IQDental API V1
  version: v1
paths:
  "/api/v1/available_terms":
    get:
      summary: List available appointment terms
      tags:
      - Available Terms
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: clinic_detail_id
        in: query
        required: true
        description: Clinic detail ID scoped to token clinic.
        schema:
          type: integer
      - name: visit_type_id
        in: query
        required: true
        description: Online reservation visit type ID.
        schema:
          type: integer
      - name: worker_id
        in: query
        required: false
        description: Optional worker ID.
        schema:
          type: integer
      - name: start_date
        in: query
        required: true
        description: 'Start date. Format: YYYY-MM-DD'
        schema:
          type: string
          example: '2026-06-01'
      - name: end_date
        in: query
        required: true
        description: 'End date. Format: YYYY-MM-DD. Maximum range: 31 days.'
        schema:
          type: string
          example: '2026-06-30'
      - name: duration
        in: query
        required: false
        description: Visit duration in seconds. If omitted, visit type reservation
          time is used.
        schema:
          type: integer
          example: 3600
      - name: minutes_offset
        in: query
        required: false
        description: Minimum offset from now in minutes.
        schema:
          type: integer
          example: 120
      - name: works_for_nfz
        in: query
        required: false
        description: Filter terms by NFZ schedule flag.
        schema:
          type: boolean
          example: false
      - name: limit
        in: query
        required: false
        description: Maximum number of returned terms. Accepts values from 1 to 500.
        schema:
          type: integer
          default: 100
      responses:
        '200':
          description: available terms listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  start_date:
                    type: string
                    example: '2026-06-01'
                  end_date:
                    type: string
                    example: '2026-06-30'
                  total:
                    type: integer
                    example: 3
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        term:
                          type: string
                          example: '1780329600_1_1'
                        worker_id:
                          type: integer
                          example: 1
                        worker_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using integration
                            encryption key.
                          example: 6fRwOB9XDFCNnhKScvibZYk=--9BsJbtyT0bDjWKi9--tMHFZaXPlFGe2bN5juDSvg==
                        office_id:
                          type: integer
                          example: 1
                        office_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using integration
                            encryption key.
                          example: gDCeGQQLolwGTZiRMLydW5QOosZ25xiy--heb6ZSjjahvMJ5fm--V0bzOwr4krKlk3Y/dU9MtA==
                        day:
                          type: string
                          example: '2026-06-01'
                        start_time:
                          type: string
                          example: '2026-06-01T16:00:00+02:00'
                        end_time:
                          type: string
                          example: '2026-06-01T17:00:00+02:00'
                        duration:
                          type: integer
                          example: 3600
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
  "/api/v1/available_terms/metadata":
    get:
      summary: List scheduling metadata for available terms
      tags:
      - Available Terms
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: clinic_detail_id
        in: query
        required: false
        description: Optional clinic detail ID scoped to token clinic. Narrows workers
          and offices.
        schema:
          type: integer
      - name: visit_type_id
        in: query
        required: false
        description: Optional online reservation visit type ID. Narrows workers and
          offices.
        schema:
          type: integer
      responses:
        '200':
          description: scheduling metadata listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  metadata:
                    type: object
                    properties:
                      clinic_details:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 1
                            name:
                              type: string
                              format: encrypted
                              description: Encrypted and signed string using integration
                                encryption key.
                      visit_types:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 1
                            name:
                              type: string
                              format: encrypted
                              description: Encrypted and signed string using integration
                                encryption key.
                            duration:
                              type: integer
                              example: 3600
                            reserved_time:
                              type: integer
                              example: 60
                      workers:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 1
                            full_name:
                              type: string
                              format: encrypted
                              description: Encrypted and signed string using integration
                                encryption key.
                            medical_license_number:
                              type: string
                              format: encrypted
                              nullable: true
                              description: Encrypted and signed string using integration
                                encryption key.
                      offices:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 1
                            name:
                              type: string
                              format: encrypted
                              description: Encrypted and signed string using integration
                                encryption key.
        '422':
          description: invalid metadata input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
  "/api/v1/clinic_details":
    get:
      summary: List all clinic details
      tags:
      - ClinicDetails
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: The page number of the resource list to fetch. Accepts values
          from 1 to 1,000,000.
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        required: false
        description: The number of records per page. Accepts values from 1 to 100.
        schema:
          type: integer
          default: 10
      - name: order_by
        in: query
        required: false
        description: The column by which to sort the results. Specifies the field
          to be used for sorting
        schema:
          type: string
          enum:
          - id
          - name
          - created_at
          - updated_at
          default: id
      - name: order_dir
        in: query
        required: false
        description: The sorting order of the records. Defines the direction of sorting
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      - name: search
        in: query
        required: false
        description: Search for clinic_details. (min length - 3 characters). Searched
          query checks for matches in name, email, address_city or address_street
        schema:
          type: string
      responses:
        '200':
          description: clinic details listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 10
                  total:
                    type: integer
                    example: 1
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: gDCeGQQLolwGTZiRMLydW5QOosZ25xiy--heb6ZSjjahvMJ5fm--V0bzOwr4krKlk3Y/dU9MtA==
                        email:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: FlcOOB8fueO0JfjkzXsV2tliCOhR7A0MDLJM3Q==--jrIokx+qffbGpyZq--e9FsNqOw9GzBMHHF/5kfWA==
                        address_street:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: 4RlKLTHVgBhF3569Nhsg3g==--Epo0MzTVgCkHmMYm--lSjySK9JxrcH9d27//YwKw==
                        address_city:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: MsBtfZKh+9GPFC2ea4E=--38ln7vHrrLlalkst--IpMkjQA15MH9phz3eolOMw==
                        address_house_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: x+vLQcYmZqoW+g08--71ZzVqLXiS+pDNsD--BtmxV94jANDnNmo5RThoIg==
                        address_flat_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: bLewuCxeaRA+zeiG--NQHlYdA8qULJntI+--xLk7LHMzmAtp+0el1qZY6w==
                        address_zip_code:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: yp0kKUZlnyOg4TpMjOM4FQ==--uRG1E/F+dXRgnj8c--5+6u/rw3PfX8OARW2pFL3w==
                        tax_identification_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: RCcN4FX+Ukncknh43rr0COAJXUo=--Lfs9Z3kSfMhbO8uF--jEkojIS3F/ETJ1JB5lp8KQ==
                        offices:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                example: 1
                              name:
                                type: string
                                format: encrypted
                                description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                                  Encrypted with uniq integration encryption key uniq
                                  for each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                                  32)`. The value is Base64-encoded.
                                example: jnLjrZOXHTJYIUNiOfjEcbkmqQ==--SaliIcWgdMctvn4/--n4JAU91Q2o1lYhqAN8eOaQ==
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 401
                  errors:
                    type: string
                    example: Invalid or missing token
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
                    properties:
                      order_by:
                        type: array
                        items:
                          type: string
                        example:
                        - 'must be one of: id, name, created_at, updated_at'
  "/api/v1/patients":
    get:
      summary: List all patients
      tags:
      - Patients
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: The page number of the resource list to fetch. Accepts values
          from 1 to 1,000,000.
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        required: false
        description: The number of records per page. Accepts values from 1 to 100.
        schema:
          type: integer
          default: 10
      - name: order_by
        in: query
        required: false
        description: The column by which to sort the results. Specifies the field
          to be used for sorting
        schema:
          type: string
          enum:
          - id
          - first_name
          - last_name
          - email
          - created_at
          - updated_at
          default: id
      - name: order_dir
        in: query
        required: false
        description: The sorting order of the records. Defines the direction of sorting
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      - name: search
        in: query
        required: false
        description: Search for patients. (min length - 3 characters). Searched query
          checks for matches in pesel, first_name, last_name, email or phone
        schema:
          type: string
      - name: updated_at_gte
        in: query
        required: false
        description: 'Filter by updated_at greater than or equal to. Format: YYYY-MM-DD
          HH:mm:ss'
        schema:
          type: string
          example: '2025-07-29 14:30:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      - name: updated_at_lte
        in: query
        required: false
        description: 'Filter by updated_at less than or equal to. Format: YYYY-MM-DD
          HH:mm:ss'
        schema:
          type: string
          example: '2025-07-29 14:30:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      - name: phone
        in: query
        required: false
        description: Exact patient phone filter.
        schema:
          type: string
      - name: email
        in: query
        required: false
        description: Exact patient email filter.
        schema:
          type: string
      - name: pesel
        in: query
        required: false
        description: Exact patient PESEL filter.
        schema:
          type: string
      responses:
        '200':
          description: patients listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 10
                  total:
                    type: integer
                    example: 1
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        first_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: ZFjxxsnCVmp4gxy+HZHb--34B7GrRKwB7yN4cL--6sA1K8jyfmG7HShhZtwlHg==
                        last_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: tsI2wUKMWhnM6nHCkw==--+MEIhwfBES8OinkM--dtlj/Cv8FQrQ5hGeh2sm0Q==
                        email:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: orpRfH032fCyC/K7QFa9eDQRrje7KbTb3UF5GjeAQofJmb5CekdDTAu9EM0qHnb+--Nv++RosXvInNmYw/--VEtixMILeaUpMc/qwDbkug==
                        phone:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: kdhfztLNcez6Xi7cbWSiA+jFbw==--bIgOrS8KGFRMB/eE--cpvZIwJ+LkZfXYihKlyoiA==
                        phone_prefix:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: pmj4mtb7SlTsI/GCiQ==--jwTJh8IZwCkwSqh2--nWVMdQ0yPXNAYdUOaMmkEw==
                        gender:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: Kj+tJ9oJxxXfih3QUAM=--Dlr+EZjn4YszJEyy--hXuoALh9BM7gWNcsJ2CGZQ==
                        pesel:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: poFFWnj6xly6AtAa3ac0tuE2dtaT--+udw4kVGAmo1w7OI--Vp8+qGlAHHEXvm1RwHKsdg==
                        address_street:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: icFKpnN2B4F+ImXgh8Gg2zv9xtOLGRDMbew=--Us2fqud0e0Bvh/rf--3OVF7lVy1styeiV10Rc4WA==
                        address_city:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: uou2HecePKXr9oF5A2+2scWuCT4nF/G7aw==--Igo9nINar6hpNw2W--vss9/zgpDoKL947OToQsWQ==
                        address_house_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: CQfRYdo+OoD/geA=--djnCnoIINHdEVTGe--bMN3y3JyzXiID/PVHrm1tw==
                        address_flat_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: qrE30CGrvnL/1gtt9gel--fZbQfa1EAgqMibPc--U5QbpYL74Ze9X+5BwY9WPg==
                        address_zip_code:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: fpKXsOrOb1vMaR5lj7OWfg==--AN8qG3kUPxSr3a36--UgV9sLhc3xX88Osjhdjhng==
                        landline_phone:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: YOY2--P6pLoLdyBy/rAbXx--N7P4jAgghfHvGZz9+xz/iw==
                        birthday:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: Vp6BfOSugPNR6+tnoZ+b+aBWMp/TaEHx4tpUwA8hkH0I--34qC/8I4CjXSYF7p--dwaBkwDmd9Po6c2R0JTykA==
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 401
                  errors:
                    type: string
                    example: Invalid or missing token
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
                    properties:
                      order_by:
                        type: array
                        items:
                          type: string
                        example:
                        - 'must be one of: id, first_name, last_name, email, created_at,
                          updated_at'
    post:
      summary: Create patient
      tags:
      - Patients
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: Idempotency-Key
        in: header
        required: true
        description: Unique key for a single create request. Reusing a key returns
          409.
        schema:
          type: string
      - name: X-Request-Id
        in: header
        required: false
        description: Optional request correlation ID returned in API errors and request
          logs.
        schema:
          type: string
      responses:
        '201':
          description: patient created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 201
                  request_id:
                    type: string
                  patient_id:
                    type: integer
        '422':
          description: missing patient payload
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: string
                    example: Patient payload is required
                  code:
                    type: string
                    example: missing_patient_payload
                  request_id:
                    type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - patient
              properties:
                patient:
                  type: object
                  required:
                  - first_name
                  - last_name
                  - phone_prefix
                  - phone
                  - current_localization_id
                  properties:
                    api_id:
                      type: string
                      example: receptionos-patient-123
                    first_name:
                      type: string
                      example: Jan
                    last_name:
                      type: string
                      example: Testowy
                    phone_prefix:
                      type: string
                      example: "+48"
                    phone:
                      type: string
                      example: 500 600 700
                    email:
                      type: string
                      example: jan.testowy@example.com
                    gender:
                      type: string
                      enum:
                      - male
                      - female
                      example: male
                    locale:
                      type: string
                      example: pl
                    current_localization_id:
                      type: integer
                      example: 1
                    pesel:
                      type: string
                      example: '90010112345'
                    without_pesel:
                      type: boolean
                      example: true
                    birthday:
                      type: string
                      example: '1990-01-01'
                    force:
                      type: boolean
                      example: false
        required: true
  "/api/v1/patients/{id}":
    get:
      summary: Show patient details
      tags:
      - Patients
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Patient ID
        schema:
          type: integer
      responses:
        '200':
          description: patient found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  patient:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      first_name:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: ZFjxxsnCVmp4gxy+HZHb--34B7GrRKwB7yN4cL--6sA1K8jyfmG7HShhZtwlHg==
                      last_name:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: tsI2wUKMWhnM6nHCkw==--+MEIhwfBES8OinkM--dtlj/Cv8FQrQ5hGeh2sm0Q==
                      email:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: orpRfH032fCyC/K7QFa9eDQRrje7KbTb3UF5GjeAQofJmb5CekdDTAu9EM0qHnb+--Nv++RosXvInNmYw/--VEtixMILeaUpMc/qwDbkug==
                      phone:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: kdhfztLNcez6Xi7cbWSiA+jFbw==--bIgOrS8KGFRMB/eE--cpvZIwJ+LkZfXYihKlyoiA==
                      phone_prefix:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: pmj4mtb7SlTsI/GCiQ==--jwTJh8IZwCkwSqh2--nWVMdQ0yPXNAYdUOaMmkEw==
                      gender:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: Kj+tJ9oJxxXfih3QUAM=--Dlr+EZjn4YszJEyy--hXuoALh9BM7gWNcsJ2CGZQ==
                      pesel:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: poFFWnj6xly6AtAa3ac0tuE2dtaT--+udw4kVGAmo1w7OI--Vp8+qGlAHHEXvm1RwHKsdg==
                      address_street:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: icFKpnN2B4F+ImXgh8Gg2zv9xtOLGRDMbew=--Us2fqud0e0Bvh/rf--3OVF7lVy1styeiV10Rc4WA==
                      address_city:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: uou2HecePKXr9oF5A2+2scWuCT4nF/G7aw==--Igo9nINar6hpNw2W--vss9/zgpDoKL947OToQsWQ==
                      address_house_number:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: CQfRYdo+OoD/geA=--djnCnoIINHdEVTGe--bMN3y3JyzXiID/PVHrm1tw==
                      address_flat_number:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: qrE30CGrvnL/1gtt9gel--fZbQfa1EAgqMibPc--U5QbpYL74Ze9X+5BwY9WPg==
                      address_zip_code:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: fpKXsOrOb1vMaR5lj7OWfg==--AN8qG3kUPxSr3a36--UgV9sLhc3xX88Osjhdjhng==
                      landline_phone:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: YOY2--P6pLoLdyBy/rAbXx--N7P4jAgghfHvGZz9+xz/iw==
                      birthday:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: Vp6BfOSugPNR6+tnoZ+b+aBWMp/TaEHx4tpUwA8hkH0I--34qC/8I4CjXSYF7p--dwaBkwDmd9Po6c2R0JTykA==
        '404':
          description: patient not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 404
                  errors:
                    type: string
                    example: Patient not found
  "/api/v1/visit_types":
    get:
      summary: List all visit_types
      tags:
      - Visit types
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: The page number of the resource list to fetch. Accepts values
          from 1 to 1,000,000.
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        required: false
        description: The number of records per page. Accepts values from 1 to 100.
        schema:
          type: integer
          default: 10
      - name: order_by
        in: query
        required: false
        description: The column by which to sort the results. Specifies the field
          to be used for sorting
        schema:
          type: string
          enum:
          - id
          - created_at
          - updated_at
          default: id
      - name: order_dir
        in: query
        required: false
        description: The sorting order of the records. Defines the direction of sorting
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      - name: search
        in: query
        required: false
        description: Search for visit types. (min length - 3 characters). Searched
          query checks for matches in id or name.
        schema:
          type: string
      responses:
        '200':
          description: Visit types listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 10
                  total:
                    type: integer
                    example: 1
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: jEKh9Q7Q7uhv00yISad/kSNdFxg11l3KsG/42zO+QkE8ias=--1hh0MAup0je7EWRa--Y+D7AhsT3uZK0osyjWH0KA==
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 401
                  errors:
                    type: string
                    example: Invalid or missing token
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
                    properties:
                      order_by:
                        type: array
                        items:
                          type: string
                        example:
                        - 'must be one of: id, name, created_at, updated_at'
  "/api/v1/visits":
    get:
      summary: List all visits
      tags:
      - Visits
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: The page number of the resource list to fetch. Accepts values
          from 1 to 1,000,000.
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        required: false
        description: The number of records per page. Accepts values from 1 to 100.
        schema:
          type: integer
          default: 10
      - name: order_by
        in: query
        required: false
        description: The column by which to sort the results. Specifies the field
          to be used for sorting
        schema:
          type: string
          enum:
          - id
          - created_at
          - updated_at
          default: id
      - name: order_dir
        in: query
        required: false
        description: The sorting order of the records. Defines the direction of sorting
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      - name: patient_id
        in: query
        required: false
        description: Filter visits by patient ID.
        schema:
          type: integer
      - name: worker_id
        in: query
        required: false
        description: Filter visits by worker ID.
        schema:
          type: integer
      - name: office_id
        in: query
        required: false
        description: Filter visits by office ID.
        schema:
          type: integer
      - name: visit_type_id
        in: query
        required: false
        description: Filter visits by visit type ID.
        schema:
          type: integer
      - name: clinic_detail_id
        in: query
        required: false
        description: Filter visits by clinic detail ID.
        schema:
          type: integer
      - name: status
        in: query
        required: false
        description: Filter visits by event status.
        schema:
          type: string
          enum:
          - new
          - started
          - completed
          - unfinished
          - absent
          - canceled
      - name: confirmation
        in: query
        required: false
        description: Filter visits by confirmation status.
        schema:
          type: string
          enum:
          - none
          - accepted
          - confirmed
          - canceled
      - name: updated_at_gte
        in: query
        required: false
        description: 'Filter by updated_at greater than or equal to. Format: YYYY-MM-DD
          HH:mm:ss'
        schema:
          type: string
          example: '2025-07-29 14:30:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      - name: updated_at_lte
        in: query
        required: false
        description: 'Filter by updated_at less than or equal to. Format: YYYY-MM-DD
          HH:mm:ss'
        schema:
          type: string
          example: '2025-07-29 14:30:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      - name: start_time_gte
        in: query
        required: false
        description: 'Filter visits by start time greater than or equal to. Format:
          YYYY-MM-DD HH:mm:ss'
        schema:
          type: string
          example: '2025-07-29 08:00:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      - name: start_time_lte
        in: query
        required: false
        description: 'Filter visits by start time less than or equal to. Format: YYYY-MM-DD
          HH:mm:ss'
        schema:
          type: string
          example: '2025-07-31 18:00:00'
          pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
      responses:
        '200':
          description: visits listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 10
                  total:
                    type: integer
                    example: 1
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        worker_id:
                          type: integer
                          example: 1
                        patient_id:
                          type: integer
                          example: 1
                        office_id:
                          type: integer
                          example: 1
                        visit_type_id:
                          type: integer
                          example: 1
                        confirmation:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: xtrKOiBSHKqkMa/S60xFc0WrBA==--KtC/DyZFgkXiDmEB--oh+1yxMRJ5+rh4cimKyH2g==
                        status:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: o7664ofFeRnpiMzXVzrG9zsrxg==--jrFNoQSLMPJou8ze--b7BQRRAXZTqHKena/EgO8w==
                        start_time:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: esvOWpIXzHQy9sfz40fjWtO+6EwEm1vgegyXd0ikVyPoeN+mbGqKeu6uBxsPKf8maW+lZEpiw1OeCbSiBhxGJ+0P52zY1WXz7DAuG/XeBtwqvbCMpnQqE1m9+Gmc6e1WT5ZHHfwM2jVMLqk=--Dhm0+dfwJOfOLOGz--fQ4BAukN6mW67a8ob/etBg==
                        end_time:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: KGs7n7uqRNOKY56Q2fdDjAnd/lPrJ+hTbLBxC/eWBV6FWbu64XiUQkNPZilO8OBlD29Q1hS+zzgMhqxfJ3noDSA7t16ijUyVBEHrlflJT6Kv3qOrKRAqDYHKkshiYgY2L/3q8OrTcN5AGrI=--s+QsBfAC8mMrIC9G--uSXN0HGQFAHuqlmMssnjPg==
                        duration:
                          type: string
                          format: encrypted
                          description: Encrypted and signed integer using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: JSu7VDj5--nUFoSANHK2NXdEGb--UBKzPBcL0qr5eY84lP1T3g==
                        late:
                          type: string
                          format: encrypted
                          description: Encrypted and signed integer using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: WOZ81MBQlQ==--AWoMMm10dlfifrCc--RJ3RPbekPIWz70oXPMniPw==
                        note:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: eoC1iguAPDPw8j0K5AKWR3wFEXI4KhoUm0c0iNwvbqY=--ardOFx3FV8cSjt+K--49TtmqeNFtKXQulJqvpGYg==
                        information:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: oTnNt6/5bmEqYw==--mCt5+WYfSJLedP/m--15BbxuWjTRtQe0f32gbk8Q==
                        first_time:
                          type: string
                          format: encrypted
                          description: Encrypted and signed boolean using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: O8qv--xZ+0hhV8/k6F0Meg--wXNdSbJmDyp/HY6wIIA31g==
                        paid:
                          type: string
                          format: encrypted
                          description: Encrypted and signed boolean using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: "+jgv--4fwZMzp7FtD7Ct47--M3fAYY4EkU7snvw2jE/Kig=="
                        prepayment_status:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: "+3nV--jZ7ZzW7tXWYcCZza--d0TF1o8v5XYkG0f4oXajew=="
                        to_pay:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: 2Qey3THGxAeUGoEFOnS3ev2L6quTlSAgug==--rBoftXcCATbB9ZWa--UxxJlwn5Tb1Z+yHOYC39Fg==
                        already_paid:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: 9Tbbcbwg9J8y7XuGOLBWE/+CHFixUg==--+5mIg6PPldNW+tuc--t0I1XJ2LYvydBOL/x8OMrg==
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 401
                  errors:
                    type: string
                    example: Invalid or missing token
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
                    properties:
                      order_by:
                        type: array
                        items:
                          type: string
                        example:
                        - 'must be one of: id, created_at, updated_at'
    post:
      summary: Create visit
      tags:
      - Visits
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: Idempotency-Key
        in: header
        required: true
        description: Unique key for a single create request. Reusing a key returns
          409.
        schema:
          type: string
      - name: X-Request-Id
        in: header
        required: false
        description: Optional request correlation ID returned in API errors and request
          logs.
        schema:
          type: string
      responses:
        '201':
          description: visit created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 201
                  request_id:
                    type: string
                  visit_id:
                    type: integer
        '422':
          description: missing visit payload
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: string
                    example: Visit payload is required
                  code:
                    type: string
                    example: missing_visit_payload
                  request_id:
                    type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - visit
              properties:
                visit:
                  type: object
                  required:
                  - patient_id
                  - clinic_detail_id
                  - worker_id
                  - office_id
                  - visit_type_id
                  - start_time
                  - end_time
                  properties:
                    api_id:
                      type: string
                      example: receptionos-visit-456
                    patient_id:
                      type: integer
                      example: 1
                    clinic_detail_id:
                      type: integer
                      example: 1
                    worker_id:
                      type: integer
                      example: 1
                    office_id:
                      type: integer
                      example: 1
                    visit_type_id:
                      type: integer
                      example: 1
                    start_time:
                      type: string
                      example: '2026-06-03 10:00:00'
                    end_time:
                      type: string
                      example: '2026-06-03 10:30:00'
                    information:
                      type: string
                      example: Pacjent z voicebota
                    important_information:
                      type: boolean
                      example: false
                    force:
                      type: boolean
                      example: false
        required: true
  "/api/v1/visits/{id}":
    get:
      summary: Show visit details
      tags:
      - Visits
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Visit ID
        schema:
          type: integer
      responses:
        '200':
          description: visit found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  visit:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 1
                      worker_id:
                        type: integer
                        example: 1
                      patient_id:
                        type: integer
                        example: 1
                      office_id:
                        type: integer
                        example: 1
                      visit_type_id:
                        type: integer
                        example: 1
                      confirmation:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: xtrKOiBSHKqkMa/S60xFc0WrBA==--KtC/DyZFgkXiDmEB--oh+1yxMRJ5+rh4cimKyH2g==
                      status:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: o7664ofFeRnpiMzXVzrG9zsrxg==--jrFNoQSLMPJou8ze--b7BQRRAXZTqHKena/EgO8w==
                      start_time:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: esvOWpIXzHQy9sfz40fjWtO+6EwEm1vgegyXd0ikVyPoeN+mbGqKeu6uBxsPKf8maW+lZEpiw1OeCbSiBhxGJ+0P52zY1WXz7DAuG/XeBtwqvbCMpnQqE1m9+Gmc6e1WT5ZHHfwM2jVMLqk=--Dhm0+dfwJOfOLOGz--fQ4BAukN6mW67a8ob/etBg==
                      end_time:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: KGs7n7uqRNOKY56Q2fdDjAnd/lPrJ+hTbLBxC/eWBV6FWbu64XiUQkNPZilO8OBlD29Q1hS+zzgMhqxfJ3noDSA7t16ijUyVBEHrlflJT6Kv3qOrKRAqDYHKkshiYgY2L/3q8OrTcN5AGrI=--s+QsBfAC8mMrIC9G--uSXN0HGQFAHuqlmMssnjPg==
                      duration:
                        type: string
                        format: encrypted
                        description: Encrypted and signed integer using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: JSu7VDj5--nUFoSANHK2NXdEGb--UBKzPBcL0qr5eY84lP1T3g==
                      late:
                        type: string
                        format: encrypted
                        description: Encrypted and signed integer using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: WOZ81MBQlQ==--AWoMMm10dlfifrCc--RJ3RPbekPIWz70oXPMniPw==
                      note:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: eoC1iguAPDPw8j0K5AKWR3wFEXI4KhoUm0c0iNwvbqY=--ardOFx3FV8cSjt+K--49TtmqeNFtKXQulJqvpGYg==
                      information:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: oTnNt6/5bmEqYw==--mCt5+WYfSJLedP/m--15BbxuWjTRtQe0f32gbk8Q==
                      first_time:
                        type: string
                        format: encrypted
                        description: Encrypted and signed boolean using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: O8qv--xZ+0hhV8/k6F0Meg--wXNdSbJmDyp/HY6wIIA31g==
                      paid:
                        type: string
                        format: encrypted
                        description: Encrypted and signed boolean using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: "+jgv--4fwZMzp7FtD7Ct47--M3fAYY4EkU7snvw2jE/Kig=="
                      prepayment_status:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: "+3nV--jZ7ZzW7tXWYcCZza--d0TF1o8v5XYkG0f4oXajew=="
                      to_pay:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: 2Qey3THGxAeUGoEFOnS3ev2L6quTlSAgug==--rBoftXcCATbB9ZWa--UxxJlwn5Tb1Z+yHOYC39Fg==
                      already_paid:
                        type: string
                        format: encrypted
                        description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                          Encrypted with uniq integration encryption key uniq for
                          each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                          32)`. The value is Base64-encoded.
                        example: 9Tbbcbwg9J8y7XuGOLBWE/+CHFixUg==--+5mIg6PPldNW+tuc--t0I1XJ2LYvydBOL/x8OMrg==
        '404':
          description: visit not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 404
                  errors:
                    type: string
                    example: Visit not found
    patch:
      summary: Updates visit
      tags:
      - Visits
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: Idempotency-Key
        in: header
        required: true
        description: Unique key for a single update request. Reusing a key returns
          409.
        schema:
          type: string
      - name: X-Request-Id
        in: header
        required: false
        description: Optional request correlation ID returned in API errors and request
          logs.
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Visit ID scoped to token clinic
        schema:
          type: integer
      responses:
        '200':
          description: visit updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  request_id:
                    type: string
                  visit_id:
                    type: integer
        '403':
          description: visit cannot be edited
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 403
                  errors:
                    type: string
                    example: Visit cannot be edited
                  code:
                    type: string
                    example: visit_not_editable
                  request_id:
                    type: string
        '422':
          description: missing visit payload
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: string
                    example: Visit payload is required
                  code:
                    type: string
                    example: missing_visit_payload
                  request_id:
                    type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - visit
              properties:
                visit:
                  type: object
                  required:
                  - patient_id
                  - clinic_detail_id
                  - worker_id
                  - office_id
                  - visit_type_id
                  - start_time
                  - end_time
                  properties:
                    patient_id:
                      type: integer
                      example: 1
                    clinic_detail_id:
                      type: integer
                      example: 1
                    worker_id:
                      type: integer
                      example: 1
                    office_id:
                      type: integer
                      example: 1
                    visit_type_id:
                      type: integer
                      example: 1
                    start_time:
                      type: string
                      example: '2026-06-04 11:00:00'
                    end_time:
                      type: string
                      example: '2026-06-04 11:30:00'
                    information:
                      type: string
                      example: Zaktualizowane przez API
                    important_information:
                      type: boolean
                      example: false
                    force:
                      type: boolean
                      example: false
        required: true
  "/api/v1/visits/{id}/cancel":
    put:
      summary: Cancel visit
      tags:
      - Visits
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: Idempotency-Key
        in: header
        required: true
        description: Unique key for a single cancel request. Reusing a key returns
          409.
        schema:
          type: string
      - name: X-Request-Id
        in: header
        required: false
        description: Optional request correlation ID returned in API errors and request
          logs.
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Visit ID scoped to token clinic
        schema:
          type: integer
      responses:
        '200':
          description: visit canceled
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  request_id:
                    type: string
                  visit_id:
                    type: integer
                  visit_status:
                    type: string
                    example: canceled
        '409':
          description: visit already canceled
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 409
                  errors:
                    type: string
                    example: Visit is already canceled
                  code:
                    type: string
                    example: visit_already_canceled
                  request_id:
                    type: string
                  visit_id:
                    type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                visit:
                  type: object
                  properties:
                    note:
                      type: string
                      example: Pacjent odwolal przez voicebota
  "/api/v1/workers":
    get:
      summary: List all workers
      tags:
      - Workers
      security:
      - bearerAuth: []
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'Bearer token for authenticating the request. Format: Bearer
          {token}'
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: The page number of the resource list to fetch. Accepts values
          from 1 to 1,000,000.
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        required: false
        description: The number of records per page. Accepts values from 1 to 100.
        schema:
          type: integer
          default: 10
      - name: order_by
        in: query
        required: false
        description: The column by which to sort the results. Specifies the field
          to be used for sorting
        schema:
          type: string
          enum:
          - id
          - first_name
          - last_name
          - email
          - created_at
          - updated_at
          default: id
      - name: order_dir
        in: query
        required: false
        description: The sorting order of the records. Defines the direction of sorting
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      - name: search
        in: query
        required: false
        description: Search for workers. (min length - 3 characters). Searched query
          checks for matches in pesel, first_name, last_name, email or phone
        schema:
          type: string
      responses:
        '200':
          description: workers listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 200
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 10
                  total:
                    type: integer
                    example: 1
                  list:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        first_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: 6fRwOB9XDFCNnhKScvibZYk=--9BsJbtyT0bDjWKi9--tMHFZaXPlFGe2bN5juDSvg==
                        last_name:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: GUe+HFpRPCjTJODp/Zt+89S6Vw==--x0aNbaOQdxOqGzlD--wIrNnc1+5XQiAH2SCoAFfQ==
                        email:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: j7g5q5Cf2FFQOsyBDozi247oCqS/+FPc--BXDUaLEMhuA9pnjT--yLFao8KXUP3626VpRXmcdA==
                        role:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: B7XQPXlq5212Mhdx6bO7--fVOq81FDosU+IUJ3--iOZdxKn1Uvh9L98xrM7qCw==
                        medical_license_number:
                          type: string
                          format: encrypted
                          description: Encrypted and signed string using ActiveSupport::MessageEncryptor.
                            Encrypted with uniq integration encryption key uniq for
                            each clinic derived via `ActiveSupport::KeyGenerator.new('api_v1_integrration_password').generate_key(integration_encryption_key,
                            32)`. The value is Base64-encoded.
                          example: 3khiHrRrWRCanCvT9ucqvI0=--RYshyCRLRuvZlYvh--Xu2FJ3uVxIi3hp194t0v3A==
        '401':
          description: unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 401
                  errors:
                    type: string
                    example: Invalid or missing token
        '422':
          description: invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    example: 422
                  errors:
                    type: object
                    properties:
                      order_by:
                        type: array
                        items:
                          type: string
                        example:
                        - 'must be one of: id, first_name, last_name, email, created_at,
                          updated_at'
servers:
- url: http://{defaultHost}
  variables:
    defaultHost:
      default:
