components:
  schemas:
    AddSpecialtyDto:
      properties:
        specialtySlug:
          description: Specialty slug to attach to the provider.
          example: adipositas
          type: string
        specialtySlugs:
          description: Specialty slugs to attach to the provider in one request.
          example:
            - adipositas
            - diabetes
          items:
            type: string
          type: array
      type: object
    ApiError:
      properties:
        correlationId:
          description: Optional request correlation ID when supplied by the client.
          example: local-smoke-001
          type: string
        error:
          description: HTTP error class.
          example: Unauthorized
          type: string
        message:
          description: Human-readable error message.
          example: Missing API key
          type: string
        statusCode:
          description: HTTP status code.
          example: 401
          type: integer
      required:
        - statusCode
        - message
        - error
      type: object
    ApiValidationError:
      additionalProperties: false
      description: Framework-level 400 of the platform partner administration surface. Identical to ApiError except that message may be the list of class-validator messages.
      properties:
        correlationId:
          description: Optional request correlation ID when supplied by the client.
          example: local-smoke-001
          type: string
        error:
          description: HTTP error class.
          example: Bad Request
          type: string
        message:
          description: "One message string, or the LIST of class-validator messages when the global ValidationPipe rejected the body. Both forms occur: the pipe always produces the list, a service-level BadRequestException with a plain string produces the single value."
          example:
            - reason should not be empty
          oneOf:
            - type: string
            - items:
                type: string
              type: array
        statusCode:
          description: HTTP status code.
          example: 400
          type: integer
      required:
        - statusCode
        - message
        - error
      type: object
    ApplyPartnerSettingsCopyDto:
      additionalProperties: false
      properties:
        appointmentTypePairs:
          description: Explicit appointment-type pairs. Source IDs may repeat; target IDs must be unique.
          items:
            $ref: "#/components/schemas/SettingsCopyAppointmentTypePairDto"
          maxItems: 20
          minItems: 0
          type: array
        previewRevision:
          description: Opaque value-free revision returned by Preview. It is bound to selectors, pairs, strategy and current copyable state.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
        reason:
          description: Required trimmed PHI-free justification. It is never stored, returned, logged or projected into audit metadata; audit records reasonProvided only.
          example: Konfiguration abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        sourcePartnerOrgId:
          description: Partner-owned source pharmacy selector.
          example: synthetic-source-01
          pattern: ^[A-Za-z0-9._:-]{1,64}$
          type: string
        strategy:
          description: Conflict strategy. OVERWRITE_CONFLICTS requires a fresh Preview generated for that strategy.
          enum:
            - FAIL_ON_CONFLICT
            - OVERWRITE_CONFLICTS
          example: FAIL_ON_CONFLICT
          type: string
        targetPartnerOrgId:
          description: Partner-owned target pharmacy selector.
          example: synthetic-target-01
          pattern: ^[A-Za-z0-9._:-]{1,64}$
          type: string
      required:
        - sourcePartnerOrgId
        - targetPartnerOrgId
        - strategy
        - previewRevision
        - reason
      type: object
    AppointmentTypeIntakeFieldDto:
      properties:
        helpText:
          description: Optional helper text.
          example: Bitte beschreiben Sie kurz Ihr Anliegen.
          maxLength: 1000
          type: string
        key:
          description: Stable custom intake field key.
          example: visit-reason
          maxLength: 80
          minLength: 1
          not:
            enum:
              - constructor
              - prototype
              - __proto__
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          type: string
        label:
          description: Patient-facing question label.
          example: Besuchergrund
          maxLength: 240
          minLength: 1
          type: string
        options:
          description: Select options when type is select.
          example:
            - label: Gesetzlich versichert
              value: gesetzlich
          items:
            $ref: "#/components/schemas/AppointmentTypeIntakeOptionDto"
          maxItems: 20
          minItems: 1
          type: array
        required:
          description: Whether this answer is required for booking.
          example: true
          type: boolean
        type:
          description: Input control type.
          enum:
            - text
            - textarea
            - select
            - boolean
            - number
          example: textarea
          type: string
        validation:
          $ref: "#/components/schemas/AppointmentTypeIntakeValidationDto"
      required:
        - key
        - label
        - type
        - required
      type: object
    AppointmentTypeIntakeFieldInputDto:
      additionalProperties: false
      oneOf:
        - not:
            required:
              - options
          properties:
            type:
              enum:
                - text
            validation:
              additionalProperties: false
              nullable: true
              properties:
                maxLength:
                  description: Text/textarea only. Inclusive maximum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea.
                  maximum: 240
                  minimum: 0
                  type: integer
                minLength:
                  description: Text/textarea only. Inclusive minimum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea. Must not exceed maxLength.
                  maximum: 240
                  minimum: 0
                  type: integer
                patternId:
                  description: "Text/textarea only; complete matches. DIGITS: ASCII digits; ALPHANUMERIC: Unicode letters/numbers, space, dot, hyphen, underscore, slash; GERMAN_POSTAL_CODE: five ASCII digits; EMAIL: stable ASCII email; PHONE_E164: + and 8–15 digits, first 1–9; ISO_DATE: YYYY-MM-DD and a real calendar date. Arbitrary regexes are forbidden."
                  enum:
                    - DIGITS
                    - ALPHANUMERIC
                    - GERMAN_POSTAL_CODE
                    - EMAIL
                    - PHONE_E164
                    - ISO_DATE
                  type: string
              type: object
        - not:
            required:
              - options
          properties:
            type:
              enum:
                - textarea
            validation:
              additionalProperties: false
              nullable: true
              properties:
                maxLength:
                  description: Text/textarea only. Inclusive maximum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea.
                  maximum: 4000
                  minimum: 0
                  type: integer
                minLength:
                  description: Text/textarea only. Inclusive minimum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea. Must not exceed maxLength.
                  maximum: 4000
                  minimum: 0
                  type: integer
                patternId:
                  description: "Text/textarea only; complete matches. DIGITS: ASCII digits; ALPHANUMERIC: Unicode letters/numbers, space, dot, hyphen, underscore, slash; GERMAN_POSTAL_CODE: five ASCII digits; EMAIL: stable ASCII email; PHONE_E164: + and 8–15 digits, first 1–9; ISO_DATE: YYYY-MM-DD and a real calendar date. Arbitrary regexes are forbidden."
                  enum:
                    - DIGITS
                    - ALPHANUMERIC
                    - GERMAN_POSTAL_CODE
                    - EMAIL
                    - PHONE_E164
                    - ISO_DATE
                  type: string
              type: object
        - not:
            required:
              - options
          properties:
            type:
              enum:
                - number
            validation:
              additionalProperties: false
              nullable: true
              properties:
                maximum:
                  description: Number only, finite inclusive upper bound.
                  maximum: 1000000000
                  minimum: -1000000000
                  type: number
                minimum:
                  description: Number only, finite inclusive lower bound; must not exceed maximum.
                  maximum: 1000000000
                  minimum: -1000000000
                  type: number
              type: object
        - properties:
            type:
              enum:
                - select
            validation:
              additionalProperties: false
              nullable: true
              properties: {}
              type: object
          required:
            - options
        - not:
            required:
              - options
          properties:
            type:
              enum:
                - boolean
            validation:
              additionalProperties: false
              nullable: true
              properties: {}
              type: object
      properties:
        helpText:
          description: "Wire superset: normalized length 0–1000 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
          example: Bitte beschreiben Sie kurz Ihr Anliegen.
          minLength: 0
          type: string
        key:
          description: "Wire superset: normalized length 1–80 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
          example: visit-reason
          minLength: 1
          not:
            enum:
              - constructor
              - prototype
              - __proto__
          pattern: ^\s*[a-z0-9]+(?:-[a-z0-9]+)*\s*$
          type: string
        label:
          description: "Wire superset: normalized length 1–240 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
          example: Besuchergrund
          minLength: 1
          pattern: \S
          type: string
        options:
          description: Required only for select. Values are unique after NFC normalization and trim.
          example:
            - label: Gesetzlich versichert
              value: gesetzlich
          items:
            $ref: "#/components/schemas/AppointmentTypeIntakeOptionInputDto"
          maxItems: 20
          minItems: 1
          type: array
        required:
          description: Whether this answer is required for booking.
          example: true
          type: boolean
        type:
          description: Input control type.
          enum:
            - text
            - textarea
            - select
            - boolean
            - number
          example: textarea
          type: string
        validation:
          $ref: "#/components/schemas/AppointmentTypeIntakeValidationDto"
      required:
        - key
        - label
        - type
        - required
      type: object
    AppointmentTypeIntakeOptionDto:
      additionalProperties: false
      properties:
        label:
          description: NFC-normalized, trimmed option label.
          example: Gesetzlich versichert
          maxLength: 240
          minLength: 1
          type: string
        value:
          description: NFC-normalized, trimmed option value, unique within the field.
          example: gesetzlich
          maxLength: 80
          minLength: 1
          type: string
      required:
        - value
        - label
      type: object
    AppointmentTypeIntakeOptionInputDto:
      additionalProperties: false
      properties:
        label:
          description: "Wire superset: normalized length 1–240 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
          example: Gesetzlich versichert
          minLength: 1
          pattern: \S
          type: string
        value:
          description: "Wire superset: normalized length 1–80 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
          example: gesetzlich
          minLength: 1
          pattern: \S
          type: string
      required:
        - value
        - label
      type: object
    AppointmentTypeIntakeValidationDto:
      additionalProperties: false
      description: Optional type-specific rules. Null or an empty object means no extra rules and is omitted in normalized reads. Unsupported type/rule combinations are rejected.
      nullable: true
      properties:
        maximum:
          description: Number only, finite inclusive upper bound.
          maximum: 1000000000
          minimum: -1000000000
          type: number
        maxLength:
          description: Text/textarea only. Inclusive maximum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea.
          maximum: 4000
          minimum: 0
          type: integer
        minimum:
          description: Number only, finite inclusive lower bound; must not exceed maximum.
          maximum: 1000000000
          minimum: -1000000000
          type: number
        minLength:
          description: Text/textarea only. Inclusive minimum Unicode code-point count after NFC and trim; at most 240 for text, 4,000 for textarea. Must not exceed maxLength.
          maximum: 4000
          minimum: 0
          type: integer
        patternId:
          description: "Text/textarea only; complete matches. DIGITS: ASCII digits; ALPHANUMERIC: Unicode letters/numbers, space, dot, hyphen, underscore, slash; GERMAN_POSTAL_CODE: five ASCII digits; EMAIL: stable ASCII email; PHONE_E164: + and 8–15 digits, first 1–9; ISO_DATE: YYYY-MM-DD and a real calendar date. Arbitrary regexes are forbidden."
          enum:
            - DIGITS
            - ALPHANUMERIC
            - GERMAN_POSTAL_CODE
            - EMAIL
            - PHONE_E164
            - ISO_DATE
          type: string
      type: object
    AppointmentTypeStandardFieldDto:
      properties:
        key:
          description: Standard patient field key controlled by appointment-type configuration.
          enum:
            - salutation
            - firstName
            - lastName
            - birthDate
            - street
            - postalCode
            - city
            - email
            - phone
            - insuranceKind
            - insuranceName
            - insurerId
            - insurerIkNumber
            - insuranceMemberId
            - insuranceStatus
          example: phone
          type: string
        required:
          description: Whether public booking must provide this visible field.
          example: false
          type: boolean
        visible:
          description: Whether Booking Web should render this standard field.
          example: true
          type: boolean
      required:
        - key
        - visible
        - required
      type: object
    CancelPartnerAppointmentDto:
      additionalProperties: false
      properties:
        reasonCode:
          description: Required closed PHI-free cancellation reason code. Free-text reasons, diagnoses, medical notes and patient contact data are rejected.
          enum:
            - PATIENT_REQUEST
            - PROVIDER_UNAVAILABLE
            - DUPLICATE
            - ADMINISTRATIVE
          example: ADMINISTRATIVE
          type: string
      required:
        - reasonCode
      type: object
    ClaimPartnerPharmacyDto:
      properties:
        partnerOrgId:
          description: Partner-controlled pharmacy identifier assigned to the console-created consumer.
          example: pharmacy-4711
          maxLength: 64
          minLength: 1
          pattern: ^[A-Za-z0-9._:-]+$
          type: string
      required:
        - partnerOrgId
      type: object
    CreateAvailabilityRuleDto:
      properties:
        dayOfWeek:
          description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
          example: 1
          maximum: 6
          minimum: 0
          type: integer
        endTime:
          description: End time in HH:mm.
          example: 12:00
          type: string
        generateFrom:
          description: First date for slot generation.
          example: 2026-05-13
          format: date
          type: string
        generateTo:
          description: Last date for slot generation.
          example: 2026-06-12
          format: date
          type: string
        slotDuration:
          description: Slot duration in minutes.
          example: 30
          type: integer
        specialtySlug:
          description: Specialty slug.
          example: adipositas
          type: string
        startTime:
          description: Start time in HH:mm.
          example: 08:30
          type: string
        timezone:
          description: IANA timezone.
          example: Europe/Berlin
          type: string
      required:
        - specialtySlug
        - dayOfWeek
        - startTime
        - endTime
        - generateFrom
        - generateTo
      type: object
    CreateBookingDto:
      properties:
        appointmentTypeSlug:
          description: Optional selected appointment type slug. When supplied, it must be active for the selected slot provider organization and specialty.
          example: adipositas-erstberatung
          type: string
        externalPatientRef:
          description: External patient reference from the integrating system.
          example: patient-12345
          type: string
        intakeResponses:
          additionalProperties:
            oneOf:
              - description: "Wire superset: normalized length 0–4000 Unicode code points after NFC and trim. OpenAPI 3 cannot express normalization before length validation; a raw maxLength would reject valid padded or decomposed input. The runtime enforces normalized limits. Request-body byte limits remain unchanged."
                minLength: 0
                type: string
              - maximum: 1000000000
                minimum: -1000000000
                type: number
              - type: boolean
          description: Appointment-type-specific intake answers keyed by known custom field keys. Strings are NFC-normalized and trimmed before rule validation and encryption. At most 30 keys and 32,768 UTF-8 bytes of canonical normalized JSON; text/textarea values have a 240/4,000-code-point ceiling, numbers must be finite and within ±1,000,000,000. Required fields, type-specific rules and select values are checked against the selected appointment type (or encrypted historical snapshot for edits). Unknown/reserved keys are rejected with generic errors, without reflecting field keys or values.
          example:
            companion-count: 1
            visit-reason: Erstberatung zur Adipositas-Therapie
          maxProperties: 30
          type: object
        patientEmail:
          description: Optional patient email.
          format: email
          type: string
        patientName:
          description: Optional patient display name.
          type: string
        patientPhone:
          description: Optional patient phone.
          type: string
        slotId:
          description: Slot to book.
          example: 0d6b61b1-a99e-480c-878f-b8f5d1be0983
          format: uuid
          type: string
        smsConfirmationAccepted:
          description: Optional explicit SMS confirmation opt-in. When true, patientPhone must use strict E.164 format (+ followed by 8 to 15 digits).
          type: boolean
      required:
        - slotId
        - externalPatientRef
      type: object
    CreateOrganizationDto:
      properties:
        email:
          description: Optional public email.
          example: kontakt@mvz-preview.example.org
          format: email
          type: string
        name:
          description: Organization display name.
          example: MVZ Preview
          type: string
        parentOrgId:
          description: "Optional parent organization. Required pattern: a PHARMACY organization may reference a PHARMACY_CHAIN parent."
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        phone:
          description: Optional public phone.
          example: +49 30 123456
          type: string
        reportingTimezone:
          description: Organization reporting timezone. Must be an exact supported IANA timezone name.
          enum:
            - Africa/Abidjan
            - Africa/Accra
            - Africa/Addis_Ababa
            - Africa/Algiers
            - Africa/Asmera
            - Africa/Bamako
            - Africa/Bangui
            - Africa/Banjul
            - Africa/Bissau
            - Africa/Blantyre
            - Africa/Brazzaville
            - Africa/Bujumbura
            - Africa/Cairo
            - Africa/Casablanca
            - Africa/Ceuta
            - Africa/Conakry
            - Africa/Dakar
            - Africa/Dar_es_Salaam
            - Africa/Djibouti
            - Africa/Douala
            - Africa/El_Aaiun
            - Africa/Freetown
            - Africa/Gaborone
            - Africa/Harare
            - Africa/Johannesburg
            - Africa/Juba
            - Africa/Kampala
            - Africa/Khartoum
            - Africa/Kigali
            - Africa/Kinshasa
            - Africa/Lagos
            - Africa/Libreville
            - Africa/Lome
            - Africa/Luanda
            - Africa/Lubumbashi
            - Africa/Lusaka
            - Africa/Malabo
            - Africa/Maputo
            - Africa/Maseru
            - Africa/Mbabane
            - Africa/Mogadishu
            - Africa/Monrovia
            - Africa/Nairobi
            - Africa/Ndjamena
            - Africa/Niamey
            - Africa/Nouakchott
            - Africa/Ouagadougou
            - Africa/Porto-Novo
            - Africa/Sao_Tome
            - Africa/Tripoli
            - Africa/Tunis
            - Africa/Windhoek
            - America/Adak
            - America/Anchorage
            - America/Anguilla
            - America/Antigua
            - America/Araguaina
            - America/Argentina/La_Rioja
            - America/Argentina/Rio_Gallegos
            - America/Argentina/Salta
            - America/Argentina/San_Juan
            - America/Argentina/San_Luis
            - America/Argentina/Tucuman
            - America/Argentina/Ushuaia
            - America/Aruba
            - America/Asuncion
            - America/Bahia
            - America/Bahia_Banderas
            - America/Barbados
            - America/Belem
            - America/Belize
            - America/Blanc-Sablon
            - America/Boa_Vista
            - America/Bogota
            - America/Boise
            - America/Buenos_Aires
            - America/Cambridge_Bay
            - America/Campo_Grande
            - America/Cancun
            - America/Caracas
            - America/Catamarca
            - America/Cayenne
            - America/Cayman
            - America/Chicago
            - America/Chihuahua
            - America/Ciudad_Juarez
            - America/Coral_Harbour
            - America/Cordoba
            - America/Costa_Rica
            - America/Coyhaique
            - America/Creston
            - America/Cuiaba
            - America/Curacao
            - America/Danmarkshavn
            - America/Dawson
            - America/Dawson_Creek
            - America/Denver
            - America/Detroit
            - America/Dominica
            - America/Edmonton
            - America/Eirunepe
            - America/El_Salvador
            - America/Fort_Nelson
            - America/Fortaleza
            - America/Glace_Bay
            - America/Godthab
            - America/Goose_Bay
            - America/Grand_Turk
            - America/Grenada
            - America/Guadeloupe
            - America/Guatemala
            - America/Guayaquil
            - America/Guyana
            - America/Halifax
            - America/Havana
            - America/Hermosillo
            - America/Indiana/Knox
            - America/Indiana/Marengo
            - America/Indiana/Petersburg
            - America/Indiana/Tell_City
            - America/Indiana/Vevay
            - America/Indiana/Vincennes
            - America/Indiana/Winamac
            - America/Indianapolis
            - America/Inuvik
            - America/Iqaluit
            - America/Jamaica
            - America/Jujuy
            - America/Juneau
            - America/Kentucky/Monticello
            - America/Kralendijk
            - America/La_Paz
            - America/Lima
            - America/Los_Angeles
            - America/Louisville
            - America/Lower_Princes
            - America/Maceio
            - America/Managua
            - America/Manaus
            - America/Marigot
            - America/Martinique
            - America/Matamoros
            - America/Mazatlan
            - America/Mendoza
            - America/Menominee
            - America/Merida
            - America/Metlakatla
            - America/Mexico_City
            - America/Miquelon
            - America/Moncton
            - America/Monterrey
            - America/Montevideo
            - America/Montserrat
            - America/Nassau
            - America/New_York
            - America/Nome
            - America/Noronha
            - America/North_Dakota/Beulah
            - America/North_Dakota/Center
            - America/North_Dakota/New_Salem
            - America/Ojinaga
            - America/Panama
            - America/Paramaribo
            - America/Phoenix
            - America/Port-au-Prince
            - America/Port_of_Spain
            - America/Porto_Velho
            - America/Puerto_Rico
            - America/Punta_Arenas
            - America/Rankin_Inlet
            - America/Recife
            - America/Regina
            - America/Resolute
            - America/Rio_Branco
            - America/Santarem
            - America/Santiago
            - America/Santo_Domingo
            - America/Sao_Paulo
            - America/Scoresbysund
            - America/Sitka
            - America/St_Barthelemy
            - America/St_Johns
            - America/St_Kitts
            - America/St_Lucia
            - America/St_Thomas
            - America/St_Vincent
            - America/Swift_Current
            - America/Tegucigalpa
            - America/Thule
            - America/Tijuana
            - America/Toronto
            - America/Tortola
            - America/Vancouver
            - America/Whitehorse
            - America/Winnipeg
            - America/Yakutat
            - Antarctica/Casey
            - Antarctica/Davis
            - Antarctica/DumontDUrville
            - Antarctica/Macquarie
            - Antarctica/Mawson
            - Antarctica/McMurdo
            - Antarctica/Palmer
            - Antarctica/Rothera
            - Antarctica/Syowa
            - Antarctica/Troll
            - Antarctica/Vostok
            - Arctic/Longyearbyen
            - Asia/Aden
            - Asia/Almaty
            - Asia/Amman
            - Asia/Anadyr
            - Asia/Aqtau
            - Asia/Aqtobe
            - Asia/Ashgabat
            - Asia/Atyrau
            - Asia/Baghdad
            - Asia/Bahrain
            - Asia/Baku
            - Asia/Bangkok
            - Asia/Barnaul
            - Asia/Beirut
            - Asia/Bishkek
            - Asia/Brunei
            - Asia/Calcutta
            - Asia/Chita
            - Asia/Colombo
            - Asia/Damascus
            - Asia/Dhaka
            - Asia/Dili
            - Asia/Dubai
            - Asia/Dushanbe
            - Asia/Famagusta
            - Asia/Gaza
            - Asia/Hebron
            - Asia/Hong_Kong
            - Asia/Hovd
            - Asia/Irkutsk
            - Asia/Jakarta
            - Asia/Jayapura
            - Asia/Jerusalem
            - Asia/Kabul
            - Asia/Kamchatka
            - Asia/Karachi
            - Asia/Katmandu
            - Asia/Khandyga
            - Asia/Krasnoyarsk
            - Asia/Kuala_Lumpur
            - Asia/Kuching
            - Asia/Kuwait
            - Asia/Macau
            - Asia/Magadan
            - Asia/Makassar
            - Asia/Manila
            - Asia/Muscat
            - Asia/Nicosia
            - Asia/Novokuznetsk
            - Asia/Novosibirsk
            - Asia/Omsk
            - Asia/Oral
            - Asia/Phnom_Penh
            - Asia/Pontianak
            - Asia/Pyongyang
            - Asia/Qatar
            - Asia/Qostanay
            - Asia/Qyzylorda
            - Asia/Rangoon
            - Asia/Riyadh
            - Asia/Saigon
            - Asia/Sakhalin
            - Asia/Samarkand
            - Asia/Seoul
            - Asia/Shanghai
            - Asia/Singapore
            - Asia/Srednekolymsk
            - Asia/Taipei
            - Asia/Tashkent
            - Asia/Tbilisi
            - Asia/Tehran
            - Asia/Thimphu
            - Asia/Tokyo
            - Asia/Tomsk
            - Asia/Ulaanbaatar
            - Asia/Urumqi
            - Asia/Ust-Nera
            - Asia/Vientiane
            - Asia/Vladivostok
            - Asia/Yakutsk
            - Asia/Yekaterinburg
            - Asia/Yerevan
            - Atlantic/Azores
            - Atlantic/Bermuda
            - Atlantic/Canary
            - Atlantic/Cape_Verde
            - Atlantic/Faeroe
            - Atlantic/Madeira
            - Atlantic/Reykjavik
            - Atlantic/South_Georgia
            - Atlantic/St_Helena
            - Atlantic/Stanley
            - Australia/Adelaide
            - Australia/Brisbane
            - Australia/Broken_Hill
            - Australia/Darwin
            - Australia/Eucla
            - Australia/Hobart
            - Australia/Lindeman
            - Australia/Lord_Howe
            - Australia/Melbourne
            - Australia/Perth
            - Australia/Sydney
            - Europe/Amsterdam
            - Europe/Andorra
            - Europe/Astrakhan
            - Europe/Athens
            - Europe/Belgrade
            - Europe/Berlin
            - Europe/Bratislava
            - Europe/Brussels
            - Europe/Bucharest
            - Europe/Budapest
            - Europe/Busingen
            - Europe/Chisinau
            - Europe/Copenhagen
            - Europe/Dublin
            - Europe/Gibraltar
            - Europe/Guernsey
            - Europe/Helsinki
            - Europe/Isle_of_Man
            - Europe/Istanbul
            - Europe/Jersey
            - Europe/Kaliningrad
            - Europe/Kiev
            - Europe/Kirov
            - Europe/Lisbon
            - Europe/Ljubljana
            - Europe/London
            - Europe/Luxembourg
            - Europe/Madrid
            - Europe/Malta
            - Europe/Mariehamn
            - Europe/Minsk
            - Europe/Monaco
            - Europe/Moscow
            - Europe/Oslo
            - Europe/Paris
            - Europe/Podgorica
            - Europe/Prague
            - Europe/Riga
            - Europe/Rome
            - Europe/Samara
            - Europe/San_Marino
            - Europe/Sarajevo
            - Europe/Saratov
            - Europe/Simferopol
            - Europe/Skopje
            - Europe/Sofia
            - Europe/Stockholm
            - Europe/Tallinn
            - Europe/Tirane
            - Europe/Ulyanovsk
            - Europe/Vaduz
            - Europe/Vatican
            - Europe/Vienna
            - Europe/Vilnius
            - Europe/Volgograd
            - Europe/Warsaw
            - Europe/Zagreb
            - Europe/Zurich
            - Indian/Antananarivo
            - Indian/Chagos
            - Indian/Christmas
            - Indian/Cocos
            - Indian/Comoro
            - Indian/Kerguelen
            - Indian/Mahe
            - Indian/Maldives
            - Indian/Mauritius
            - Indian/Mayotte
            - Indian/Reunion
            - Pacific/Apia
            - Pacific/Auckland
            - Pacific/Bougainville
            - Pacific/Chatham
            - Pacific/Easter
            - Pacific/Efate
            - Pacific/Enderbury
            - Pacific/Fakaofo
            - Pacific/Fiji
            - Pacific/Funafuti
            - Pacific/Galapagos
            - Pacific/Gambier
            - Pacific/Guadalcanal
            - Pacific/Guam
            - Pacific/Honolulu
            - Pacific/Kiritimati
            - Pacific/Kosrae
            - Pacific/Kwajalein
            - Pacific/Majuro
            - Pacific/Marquesas
            - Pacific/Midway
            - Pacific/Nauru
            - Pacific/Niue
            - Pacific/Norfolk
            - Pacific/Noumea
            - Pacific/Pago_Pago
            - Pacific/Palau
            - Pacific/Pitcairn
            - Pacific/Ponape
            - Pacific/Port_Moresby
            - Pacific/Rarotonga
            - Pacific/Saipan
            - Pacific/Tahiti
            - Pacific/Tarawa
            - Pacific/Tongatapu
            - Pacific/Truk
            - Pacific/Wake
            - Pacific/Wallis
          example: Europe/Berlin
          type: string
        slug:
          description: Organization slug.
          example: mvz-preview
          type: string
        type:
          description: Organization type.
          enum:
            - SOLO_PRACTICE
            - MVZ
            - CLINIC
            - PHARMACY
            - PHARMACY_CHAIN
          example: MVZ
          type: string
      required:
        - slug
        - name
        - type
      type: object
    CreatePartnerAvailabilityRuleDto:
      oneOf:
        - properties:
            dayOfWeek:
              description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
              example: 1
              maximum: 6
              minimum: 0
              type: integer
            endTime:
              description: End time in HH:mm.
              example: 12:00
              type: string
            generateFrom:
              description: First date for slot generation.
              example: 2026-05-13
              format: date
              type: string
            generateTo:
              description: Last date for slot generation.
              example: 2026-06-12
              format: date
              type: string
            slotDuration:
              description: Slot duration in minutes.
              example: 30
              type: integer
            specialtySlug:
              description: Specialty slug.
              example: adipositas
              type: string
            startTime:
              description: Start time in HH:mm.
              example: 08:30
              type: string
            timezone:
              description: IANA timezone.
              example: Europe/Berlin
              type: string
          required:
            - specialtySlug
            - dayOfWeek
            - startTime
            - endTime
            - generateFrom
            - generateTo
          type: object
        - properties:
            rules:
              description: Availability rules to create in one transaction.
              example:
                - dayOfWeek: 1
                  endTime: 12:00
                  generateFrom: 2026-07-01
                  generateTo: 2026-07-31
                  slotDuration: 30
                  specialtySlug: adipositas
                  startTime: 08:30
                  timezone: Europe/Berlin
                - dayOfWeek: 3
                  endTime: 17:00
                  generateFrom: 2026-07-01
                  generateTo: 2026-07-31
                  slotDuration: 30
                  specialtySlug: adipositas
                  startTime: 14:00
                  timezone: Europe/Berlin
              items:
                properties:
                  dayOfWeek:
                    description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
                    example: 1
                    maximum: 6
                    minimum: 0
                    type: integer
                  endTime:
                    description: End time in HH:mm.
                    example: 12:00
                    type: string
                  generateFrom:
                    description: First date for slot generation.
                    example: 2026-05-13
                    format: date
                    type: string
                  generateTo:
                    description: Last date for slot generation.
                    example: 2026-06-12
                    format: date
                    type: string
                  slotDuration:
                    description: Slot duration in minutes.
                    example: 30
                    type: integer
                  specialtySlug:
                    description: Specialty slug.
                    example: adipositas
                    type: string
                  startTime:
                    description: Start time in HH:mm.
                    example: 08:30
                    type: string
                  timezone:
                    description: IANA timezone.
                    example: Europe/Berlin
                    type: string
                required:
                  - specialtySlug
                  - dayOfWeek
                  - startTime
                  - endTime
                  - generateFrom
                  - generateTo
                type: object
              type: array
          required:
            - rules
          type: object
      properties: {}
      type: object
    CreatePartnerLoginLinkDto:
      properties:
        userRef:
          description: Optional partner-stable user reference (max 128 chars, charset A-Za-z0-9._:@-). Without userRef the link targets the pharmacy owner backoffice user. An unknown userRef creates a restricted PHARMACY_STAFF backoffice user just in time (never an admin); the raw value is never persisted, only a hash.
          example: portal-user-77
          type: string
      type: object
    CreatePartnerOffboardingRequestDto:
      properties:
        effectiveAt:
          description: Optional requested effective date.
          example: 2026-08-01T00:00:00.000Z
          format: date-time
          type: string
        reason:
          description: Optional PHI-free termination reason from the partner system.
          example: Vertrag beendet
          type: string
      type: object
    CreatePartnerPharmacyDto:
      properties:
        acceptedDataProcessing:
          description: "Must be true: the partner confirms the pharmacy accepted the data processing terms."
          example: true
          type: boolean
        partner:
          description: Partner channel identifier.
          enum:
            - gedisa
            - medivise
          example: gedisa
          type: string
        partnerOrgId:
          description: Partner-controlled pharmacy identifier in the partner namespace. Registrations are idempotent per (partner, partnerOrgId).
          example: pharmacy-4711
          type: string
        pharmacy:
          description: Pharmacy master data. All fields are required (AF-189) so the tenant is fully usable without manual follow-up.
          properties:
            address:
              description: Pharmacy address.
              properties:
                city:
                  description: City.
                  example: Hamburg
                  type: string
                postalCode:
                  description: Postal code.
                  example: "20457"
                  type: string
                street:
                  description: Street and number.
                  example: Musterstr. 1
                  type: string
              required:
                - street
                - postalCode
                - city
              type: object
            desiredSlug:
              description: "Desired tenant slug, and at the same time the DNS label of the pharmacy tenant host <slug>.<base domain>. Tightened with AF-364: no leading or trailing hyphen, no double hyphen, at most 63 characters, no platform-reserved name, no reserved prefix partner-, and no slug already used by a platform partner (409 CONSUMER_SLUG_TAKEN_BY_PARTNER)."
              example: beispiel-apotheke-4711
              maxLength: 63
              minLength: 1
              pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
              type: string
            organizationDisplayName:
              description: Pharmacy display name.
              example: Beispiel Apotheke
              type: string
            organizationLegalName:
              description: Legal name of the pharmacy.
              example: Beispiel Apotheke e.K.
              type: string
            primaryContactEmail:
              description: Owner contact email.
              example: kontakt@example.test
              format: email
              type: string
            primaryContactName:
              description: Owner contact of the pharmacy.
              example: Synthetischer Kontakt
              type: string
            primaryContactPhone:
              description: Owner contact phone.
              example: +49 40 123456
              type: string
          required:
            - organizationDisplayName
            - organizationLegalName
            - desiredSlug
            - primaryContactName
            - primaryContactEmail
            - primaryContactPhone
            - address
          type: object
      required:
        - partner
        - partnerOrgId
        - pharmacy
        - acceptedDataProcessing
      type: object
    CreatePartnerPharmacyRoomDto:
      properties:
        availability:
          description: Initial weekly room availability rule. The room is created with this active rule.
          properties:
            dayOfWeek:
              description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
              example: 1
              maximum: 6
              minimum: 0
              type: integer
            endTime:
              description: End time in exact HH:mm format and strictly later than startTime. 24:00 is accepted as the end of the local day.
              example: 12:00
              pattern: ^(([01]\d|2[0-3]):[0-5]\d|24:00)$
              type: string
            startTime:
              description: Start time in exact HH:mm format. 24:00 is allowed only as endTime because endTime must be strictly later than startTime.
              example: 08:00
              pattern: ^(([01]\d|2[0-3]):[0-5]\d|24:00)$
              type: string
            timezone:
              description: Optional canonical IANA timezone accepted by the runtime, such as Europe/Berlin.
              example: Europe/Berlin
              type: string
            validFrom:
              description: Optional first local date on which this room rule is valid.
              example: 2026-06-01
              format: date
              nullable: true
              type: string
            validUntil:
              description: Optional inclusive last local date on which this room rule is valid. When validFrom is supplied, validUntil must be on or after validFrom. Null means open-ended.
              example: 2026-12-31
              format: date
              nullable: true
              type: string
          required:
            - dayOfWeek
            - startTime
            - endTime
          type: object
        name:
          description: Room display name. Leading and trailing whitespace is removed; at least one non-whitespace character must remain.
          example: Beratungsraum 1
          maxLength: 120
          pattern: \S
          type: string
        pharmacyOrgId:
          description: Pharmacy organization identifier that owns the consultation room.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
      required:
        - pharmacyOrgId
        - name
        - availability
      type: object
    CreatePartnerWebhookDto:
      properties:
        auth:
          description: Optional OAuth2 client-credentials configuration for receivers that expect bearer-authenticated deliveries instead of the default HMAC-signed mode. Omit entirely to keep HMAC signing.
          properties:
            clientId:
              description: OAuth2 client identifier.
              example: akflow-webhook-client
              type: string
            clientSecret:
              description: "OAuth2 client secret. Write-only: accepted on creation, stored encrypted, and never included in any response."
              example: <CLIENT_SECRET>
              type: string
              writeOnly: true
            mode:
              description: Fixed delivery auth mode discriminator.
              enum:
                - OAUTH2_CLIENT_CREDENTIALS
              example: OAUTH2_CLIENT_CREDENTIALS
              type: string
            scope:
              description: Optional OAuth2 scope sent as the `scope` form parameter on the token request. Set it when the partner channel requires a specific scope value for webhook deliveries.
              example: webhooks:deliver
              type: string
            tokenUrl:
              description: HTTPS token endpoint for the client-credentials grant. Subject to the same SSRF host restrictions as the webhook url.
              example: https://auth.partner.example/oauth2/token
              type: string
          required:
            - mode
            - tokenUrl
            - clientId
            - clientSecret
          type: object
        events:
          description: Subscribed partner events. This enum is derived from the authoritative ALLOWED_PARTNER_WEBHOOK_EVENTS constant (partner-webhooks.service.ts), so it cannot drift from the values the API actually accepts.
          example:
            - appointment.created
            - appointment.cancelled
          items:
            enum:
              - appointment.created
              - appointment.updated
              - appointment.cancelled
              - appointment.completed
              - appointment.failed
              - assessment.completed
              - partner_onboarding.completed
              - partner_onboarding.failed
              - partner_offboarding.completed
              - partner_offboarding.failed
            type: string
          type: array
        url:
          description: HTTPS receiver URL. IP literals, localhost and cluster-internal hosts are rejected.
          example: https://webhooks.partner.example/akflow
          type: string
      required:
        - url
        - events
      type: object
    CreateProviderDto:
      properties:
        authIssuer:
          description: Optional provider auth issuer. Omit with externalId to create an unlinked pending provider identity.
          example: https://login.example.org/realms/partner
          format: uri
          type: string
        availabilityRules:
          description: Optional availability rules to create and generate slots for during provider creation. Referenced specialties are attached to the provider before rule creation.
          example:
            - dayOfWeek: 1
              endTime: 12:00
              generateFrom: 2026-07-01
              generateTo: 2026-07-31
              slotDuration: 30
              specialtySlug: adipositas
              startTime: 08:30
              timezone: Europe/Berlin
          items:
            properties:
              dayOfWeek:
                description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
                example: 1
                maximum: 6
                minimum: 0
                type: integer
              endTime:
                description: End time in HH:mm.
                example: 12:00
                type: string
              generateFrom:
                description: First date for slot generation.
                example: 2026-05-13
                format: date
                type: string
              generateTo:
                description: Last date for slot generation.
                example: 2026-06-12
                format: date
                type: string
              slotDuration:
                description: Slot duration in minutes.
                example: 30
                type: integer
              specialtySlug:
                description: Specialty slug.
                example: adipositas
                type: string
              startTime:
                description: Start time in HH:mm.
                example: 08:30
                type: string
              timezone:
                description: IANA timezone.
                example: Europe/Berlin
                type: string
            required:
              - specialtySlug
              - dayOfWeek
              - startTime
              - endTime
              - generateFrom
              - generateTo
            type: object
          type: array
        bio:
          description: Optional public profile bio.
          example: Facharzt für Innere Medizin.
          type: string
        email:
          description: Provider email.
          example: ben.koch@example.org
          format: email
          type: string
        externalId:
          description: Optional external identity subject or email. Must be supplied together with authIssuer when linking an IdP identity.
          example: ben.koch@example.org
          type: string
        firstName:
          description: First name.
          example: Ben
          type: string
        lastName:
          description: Last name.
          example: Koch
          type: string
        organizationId:
          description: Organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        phone:
          description: Optional phone.
          example: +49 151 12345678
          type: string
        photoUrl:
          description: Optional profile photo URL.
          example: https://example.com/ben-koch.jpg
          format: uri
          type: string
        role:
          description: Provider role.
          enum:
            - DOCTOR
            - ORG_ADMIN
            - PHARMACY_STAFF
          example: DOCTOR
          type: string
        salutation:
          description: Optional provider salutation code.
          enum:
            - MR
            - MS
            - MX
            - NONE
          example: MR
          type: string
        specialtySlugs:
          description: Optional specialty slugs to attach during provider creation.
          example:
            - adipositas
            - diabetes
          items:
            type: string
          type: array
        title:
          description: Optional controlled provider title.
          enum:
            - Dr.
            - Dr. med.
            - Dr. medic
            - Dr. med. dent.
            - Dr. rer. nat.
            - Dr. Dr.
            - Prof.
            - Prof. Dr.
            - Prof. Dr. med.
            - PD Dr.
            - Priv.-Doz. Dr.
          example: Dr. med.
          type: string
      required:
        - organizationId
        - email
        - role
        - firstName
        - lastName
      type: object
    OrganizationKimAddressDto:
      additionalProperties: false
      properties:
        consumerId:
          format: uuid
          type: string
        kimAddress:
          description: Current KIM address of the active pharmacy organization. Null means that no KIM address is configured.
          example: team@praxis.kim.telematik
          format: email
          maxLength: 254
          nullable: true
          pattern: ^[^\u0000-\u001f\u007f-\u009f]+@[^\s@]+\.[kK][iI][mM]\.[tT][eE][lL][eE][mM][aA][tT][iI][kK]$
          type: string
        organizationId:
          format: uuid
          type: string
      required:
        - consumerId
        - organizationId
        - kimAddress
      type: object
    PartnerAdditionalConfirmationRecipientsDto:
      additionalProperties: false
      properties:
        consumerId:
          format: uuid
          type: string
        organizationId:
          format: uuid
          type: string
        recipients:
          items:
            format: email
            maxLength: 254
            type: string
          maxItems: 5
          type: array
      required:
        - consumerId
        - organizationId
        - recipients
      type: object
    PartnerAppointmentDto:
      properties:
        appointmentId:
          description: Tenant-local appointment identifier.
          example: 8cb6d8b8-a582-4cd2-8095-f60537a0d3dc
          format: uuid
          type: string
        appointmentTypeName:
          description: Appointment type display name, or null when absent.
          example: Partner Check
          nullable: true
          type: string
        appointmentTypeSlug:
          description: Appointment type slug, or null when the booking has no selected type.
          example: partner-check
          nullable: true
          type: string
        cancelledAt:
          description: UTC cancellation timestamp, or null when not cancelled.
          example: null
          format: date-time
          nullable: true
          type: string
        caseId:
          description: Partner case reference (the case id supplied by the partner platform) present when the booking was created with one, or null when absent. Correlation-only; never exposed in patient-facing responses.
          example: CASE-2026-000123
          nullable: true
          type: string
        endTime:
          description: UTC appointment end timestamp.
          example: 2026-06-03T08:30:00.000Z
          format: date-time
          type: string
        externalPatientRef:
          description: Partner-controlled external patient reference. This is the only patient reference exposed by the partner Appointment API.
          example: partner-patient-1
          nullable: true
          type: string
        organization:
          description: Provider organization.
          properties:
            id:
              description: Organization identifier.
              example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
              format: uuid
              type: string
            name:
              description: Organization display name.
              example: Partner Apotheke
              type: string
            slug:
              description: Organization slug.
              example: partner-apotheke
              type: string
          type: object
        organizationId:
          description: Provider organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        providerId:
          description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          format: uuid
          type: string
        providerName:
          description: Provider display name.
          example: Dr. med. Ada Partner
          type: string
        source:
          description: Booking source.
          example: S2S
          type: string
        specialtyName:
          description: Specialty display name.
          example: Adipositas
          type: string
        specialtySlug:
          description: Specialty slug.
          example: adipositas
          type: string
        startTime:
          description: UTC appointment start timestamp.
          example: 2026-06-03T08:00:00.000Z
          format: date-time
          type: string
        status:
          description: Appointment status.
          example: CONFIRMED
          type: string
          x-extensible-enum:
            - CONFIRMED
            - COMPLETED
            - NO_SHOW
            - CANCELLED
            - PENDING_PARTNER_CONFIRMATION
        video:
          description: Optional video session state.
          properties:
            sessionRef:
              description: Opaque video session reference.
              example: ak-123
              type: string
            status:
              description: Video session status.
              example: REQUESTED
              type: string
          type: object
      required:
        - appointmentId
        - status
        - source
        - providerId
        - providerName
        - organizationId
        - organization
        - specialtySlug
        - specialtyName
        - appointmentTypeSlug
        - appointmentTypeName
        - externalPatientRef
        - caseId
        - startTime
        - endTime
        - cancelledAt
        - video
      type: object
    PartnerAppointmentsResponseDto:
      properties:
        appointments:
          description: Tenant-local appointments sorted by start time.
          items:
            $ref: "#/components/schemas/PartnerAppointmentDto"
          type: array
        range:
          description: Requested local date range.
          properties:
            from:
              description: Start date.
              example: 2026-06-01
              format: date
              type: string
            to:
              description: End date.
              example: 2026-06-07
              format: date
              type: string
          type: object
      required:
        - range
        - appointments
      type: object
    PartnerAppointmentTypeEmailMessageSettingsDto:
      additionalProperties: false
      properties:
        appointmentTypeId:
          description: Scoped appointment-type identifier.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          format: uuid
          type: string
        configured:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveEmailMessageSettingsDto"
        inheritedFrom:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsInheritedDto"
        organizationId:
          description: Owning pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Opaque SHA-256 base64url revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
        sources:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsSourcesDto"
      required:
        - consumerId
        - organizationId
        - appointmentTypeId
        - configured
        - inheritedFrom
        - effective
        - sources
        - revision
      type: object
    PartnerAppointmentTypeEmailReminderDto:
      additionalProperties: false
      properties:
        appointmentTypeId:
          description: Scoped appointment-type identifier.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          format: uuid
          type: string
        configured:
          $ref: "#/components/schemas/PartnerEmailReminderConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveEmailReminderDto"
        inheritedFrom:
          $ref: "#/components/schemas/PartnerEmailReminderInheritedDto"
        organizationId:
          description: Owning pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-17T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - consumerId
        - organizationId
        - appointmentTypeId
        - configured
        - inheritedFrom
        - effective
        - revision
      type: object
    PartnerAppointmentTypeSchedulingPolicyDto:
      additionalProperties: false
      properties:
        appointmentTypeId:
          description: Scoped appointment-type identifier.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          format: uuid
          type: string
        configured:
          $ref: "#/components/schemas/PartnerSchedulingPolicyConfiguredDto"
        effective:
          $ref: "#/components/schemas/PartnerSchedulingPolicyEffectiveDto"
        inheritedFrom:
          additionalProperties: false
          description: Organization-level values from which null appointment-type fields inherit before system defaults are applied.
          properties:
            cancellationDeadlineHours:
              description: Cancellation deadline applied to newly evaluated booking decisions, in hours. Null selects inheritance; 0 is an explicit configured value.
              example: null
              maximum: 8760
              minimum: 0
              nullable: true
              type: integer
            followUpMinutes:
              description: Follow-up time reserved after a newly evaluated booking, in minutes. Null selects inheritance; 0 is an explicit configured value.
              example: null
              maximum: 480
              minimum: 0
              nullable: true
              type: integer
            minLeadMinutes:
              description: Minimum lead time required when a new booking decision is evaluated, in minutes. Null selects inheritance; 0 is an explicit configured value.
              example: null
              maximum: 43200
              minimum: 0
              nullable: true
              type: integer
            prepMinutes:
              description: Preparation time reserved before a newly evaluated booking, in minutes. Null selects inheritance; 0 is an explicit configured value.
              example: null
              maximum: 480
              minimum: 0
              nullable: true
              type: integer
          required:
            - prepMinutes
            - followUpMinutes
            - minLeadMinutes
            - cancellationDeadlineHours
          type: object
        organizationId:
          description: Owning organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
      required:
        - appointmentTypeId
        - organizationId
        - configured
        - inheritedFrom
        - effective
      type: object
    PartnerAppointmentTypeSmsConfirmationConfiguredDto:
      additionalProperties: false
      properties:
        enabled:
          description: Appointment-type switch, or null to inherit the organization switch.
          nullable: true
          type: boolean
        text:
          description: Configured normalized GSM-7 SMS text, or null to inherit the organization text and then the safe system template.
          maxLength: 160
          nullable: true
          type: string
      required:
        - enabled
        - text
      type: object
    PartnerAppointmentTypeSmsConfirmationDto:
      additionalProperties: false
      properties:
        appointmentTypeId:
          description: Scoped appointment-type identifier.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          format: uuid
          type: string
        configured:
          $ref: "#/components/schemas/PartnerAppointmentTypeSmsConfirmationConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveSmsConfirmationDto"
        inheritedFrom:
          $ref: "#/components/schemas/PartnerOrganizationSmsConfirmationConfiguredDto"
          description: Organization values inherited by null appointment-type fields before the system text fallback.
        organizationId:
          description: Owning pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-16T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - consumerId
        - organizationId
        - appointmentTypeId
        - configured
        - inheritedFrom
        - effective
        - revision
      type: object
    PartnerAppointmentTypesResponseDto:
      properties:
        allowedSpecialties:
          description: Specialties enabled for the authenticated consumer tenant.
          items:
            properties:
              name:
                description: Specialty display name.
                example: Adipositas
                type: string
              slug:
                description: Specialty slug.
                example: adipositas
                type: string
            required:
              - slug
              - name
            type: object
          type: array
        appointmentTypes:
          description: Tenant-local appointment types. Required and optional booking keys are described by requiredFields, standardFields and customIntakeFields.
          items:
            description: Appointment type.
            properties:
              bookingWebVisible:
                description: Whether this appointment type is visible in Booking Web.
                example: true
                type: boolean
              bufferMinutes:
                description: "Buffer after appointment in minutes. Deprecated: has no effect on scheduling. Superseded by the appointment type's prepMinutes and followUpMinutes (AF-323)."
                example: 0
                type: integer
              consentVersionLabel:
                description: Consent version label.
                example: v1
                type: string
              currency:
                description: Optional ISO 4217 currency.
                example: EUR
                nullable: true
                type: string
              customIntakeFields:
                description: Complete ordered custom-field array. Empty clears fields. At most 61,440 UTF-8 bytes of canonical normalized JSON; unrelated intakeConfig properties are preserved.
                items:
                  $ref: "#/components/schemas/AppointmentTypeIntakeFieldDto"
                maxItems: 30
                type: array
              durationMinutes:
                description: Appointment duration in minutes.
                example: 30
                type: integer
              id:
                description: Appointment type identifier.
                example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
                format: uuid
                type: string
              isActive:
                description: Whether this appointment type is active.
                example: true
                type: boolean
              mode:
                description: Appointment mode.
                enum:
                  - IN_PERSON
                  - VIDEO
                example: IN_PERSON
                type: string
              name:
                description: Appointment type display name.
                example: Partner Check
                type: string
              organization:
                description: Owning organization.
                properties:
                  id:
                    description: Organization identifier.
                    example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
                    format: uuid
                    type: string
                  name:
                    description: Organization display name.
                    example: Partner Apotheke
                    type: string
                  slug:
                    description: Organization slug.
                    example: partner-apotheke
                    type: string
                type: object
              organizationId:
                description: Organization identifier.
                example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
                format: uuid
                type: string
              paymentMode:
                description: Payment mode.
                enum:
                  - NONE
                  - SELF_PAY
                example: NONE
                type: string
              priceCents:
                description: Optional price in cents.
                example: 9900
                nullable: true
                type: integer
              requiredFields:
                description: Compatibility list of required standard patient field keys.
                example:
                  - firstName
                  - lastName
                  - email
                items:
                  type: string
                type: array
              revision:
                description: Opaque base64url revision of normalized custom fields. Return the latest read value unchanged; stale revisions produce 409. It is not a credential and does not describe the whole appointment type.
                maxLength: 43
                minLength: 43
                pattern: ^[A-Za-z0-9_-]{43}$
                type: string
              slug:
                description: Appointment type slug.
                example: partner-check
                type: string
              specialtyName:
                description: Specialty display name.
                example: Adipositas
                type: string
              specialtySlug:
                description: Specialty slug.
                example: adipositas
                type: string
              standardFields:
                description: Standard patient fields controlled by this appointment type.
                items:
                  $ref: "#/components/schemas/AppointmentTypeStandardFieldDto"
                type: array
            type: object
          type: array
      required:
        - allowedSpecialties
        - appointmentTypes
      type: object
    PartnerAvailabilityRuleResponseDto:
      properties:
        dayOfWeek:
          description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
          example: 1
          maximum: 6
          minimum: 0
          type: integer
        endTime:
          description: End time in HH:mm.
          example: 12:00
          type: string
        isActive:
          description: Whether the rule is active.
          example: true
          type: boolean
        organization:
          description: Provider organization.
          properties:
            id:
              description: Organization identifier.
              example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
              format: uuid
              type: string
            name:
              description: Organization display name.
              example: MVZ Preview
              type: string
            slug:
              description: Organization slug.
              example: mvz-preview
              type: string
          type: object
        organizationId:
          description: Provider organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        providerId:
          description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          format: uuid
          type: string
        ruleId:
          description: Availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          format: uuid
          type: string
        slotDuration:
          description: Slot duration in minutes.
          example: 30
          type: integer
        slotsCreated:
          description: Number of slots generated by create/update operations.
          example: 12
          type: integer
        slotsRemoved:
          description: Number of unbooked slots removed by deactivate operations.
          example: 12
          type: integer
        specialtyName:
          description: Specialty display name.
          example: Adipositas
          type: string
        specialtySlug:
          description: Specialty slug.
          example: adipositas
          type: string
        startTime:
          description: Start time in HH:mm.
          example: 09:00
          type: string
        timezone:
          description: IANA timezone.
          example: Europe/Berlin
          type: string
        validFrom:
          description: First local date on which this rule is valid.
          example: 2026-06-01
          format: date
          nullable: true
          type: string
        validUntil:
          description: Last local date on which this rule is valid.
          example: 2026-06-30
          format: date
          nullable: true
          type: string
      required:
        - ruleId
        - providerId
        - organizationId
        - organization
        - specialtySlug
        - specialtyName
        - dayOfWeek
        - startTime
        - endTime
        - slotDuration
        - timezone
        - validFrom
        - validUntil
        - isActive
      type: object
    PartnerAvailabilityRulesResponseDto:
      properties:
        rules:
          description: Provider availability rules sorted by weekday and start time.
          items:
            $ref: "#/components/schemas/PartnerAvailabilityRuleResponseDto"
          type: array
        totalSlotsCreated:
          description: Total number of slots generated by a batch create operation.
          example: 24
          type: integer
      required:
        - rules
      type: object
    PartnerChannelWebhookDto:
      properties:
        createdAt:
          description: Creation timestamp.
          example: 2026-07-03T10:00:00.000Z
          format: date-time
          type: string
        deliveryAuthMode:
          description: How deliveries authenticate against the receiver.
          enum:
            - HMAC
            - OAUTH2_CLIENT_CREDENTIALS
          example: OAUTH2_CLIENT_CREDENTIALS
          type: string
        events:
          description: Subscribed partner events.
          example:
            - appointment.created
            - appointment.cancelled
          items:
            type: string
          type: array
        id:
          description: Webhook identifier.
          example: c0d13fd1-f37a-4537-9841-4d4ee0e3f6b8
          format: uuid
          type: string
        isActive:
          description: Whether the webhook is active.
          example: true
          type: boolean
        scope:
          description: "Always channel: the subscription belongs to the partner channel, not to a single pharmacy."
          enum:
            - channel
          example: channel
          type: string
        secret:
          description: Signing secret, returned exactly once and only in HMAC mode. Verify x-akflow-signature = sha256 HMAC over `${x-akflow-timestamp}.${body}`.
          example: <ONE_TIME_SIGNING_SECRET>
          readOnly: true
          type: string
          x-akflow-one-time-credential: true
        url:
          description: Receiver URL that serves every pharmacy of the channel.
          example: https://webhooks.partner.example/akflow
          type: string
      type: object
    PartnerEffectiveEmailMessageSettingsDto:
      additionalProperties: false
      properties:
        confirmationAdditionalText:
          description: Additional confirmation text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        confirmationIntroText:
          description: Confirmation introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        logoVisibility:
          description: Effective logo visibility after inheritance.
          enum:
            - SHOW
            - HIDE
          type: string
        reminderAdditionalText:
          description: Additional reminder text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        reminderIntroText:
          description: Reminder introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
      required:
        - confirmationIntroText
        - confirmationAdditionalText
        - reminderIntroText
        - reminderAdditionalText
        - logoVisibility
      type: object
    PartnerEffectiveEmailReminderDto:
      additionalProperties: false
      properties:
        enabled:
          description: Effective email reminder switch after inheritance.
          example: false
          type: boolean
        enabledSource:
          description: Configuration level supplying the effective enabled value.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
        leadMinutes:
          description: Effective lead time in minutes after inheritance.
          example: 1440
          maximum: 43200
          minimum: 60
          type: integer
        leadMinutesSource:
          description: Configuration level supplying the effective lead time.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
      required:
        - enabled
        - leadMinutes
        - enabledSource
        - leadMinutesSource
      type: object
    PartnerEffectiveSmsConfirmationDto:
      additionalProperties: false
      properties:
        enabled:
          description: Effective SMS confirmation switch after inheritance.
          example: true
          type: boolean
        enabledSource:
          description: Configuration level supplying the effective enabled value.
          enum:
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: ORGANIZATION
          type: string
        text:
          description: Effective normalized single-segment GSM-7 SMS text after inheritance.
          maxLength: 160
          type: string
        textSource:
          description: Configuration level supplying the effective text.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
      required:
        - enabled
        - text
        - enabledSource
        - textSource
      type: object
    PartnerEmailMessageSettingsConfiguredDto:
      additionalProperties: false
      properties:
        confirmationAdditionalText:
          description: Additional confirmation text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        confirmationIntroText:
          description: Confirmation introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        logoVisibility:
          description: Configured logo visibility, or null to inherit.
          enum:
            - SHOW
            - HIDE
          nullable: true
          type: string
        reminderAdditionalText:
          description: Additional reminder text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        reminderIntroText:
          description: Reminder introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
      required:
        - confirmationIntroText
        - confirmationAdditionalText
        - reminderIntroText
        - reminderAdditionalText
        - logoVisibility
      type: object
    PartnerEmailMessageSettingsInheritedDto:
      additionalProperties: false
      properties:
        confirmationAdditionalText:
          description: Additional confirmation text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        confirmationIntroText:
          description: Confirmation introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        logoVisibility:
          description: Effective logo visibility after inheritance.
          enum:
            - SHOW
            - HIDE
          type: string
        reminderAdditionalText:
          description: Additional reminder text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        reminderIntroText:
          description: Reminder introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
      required:
        - confirmationIntroText
        - confirmationAdditionalText
        - reminderIntroText
        - reminderAdditionalText
        - logoVisibility
      type: object
    PartnerEmailMessageSettingsSourcesDto:
      additionalProperties: false
      properties:
        confirmationAdditionalText:
          description: Configuration level supplying confirmationAdditionalText.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
        confirmationIntroText:
          description: Configuration level supplying confirmationIntroText.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
        logoVisibility:
          description: Configuration level supplying logoVisibility.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
        reminderAdditionalText:
          description: Configuration level supplying reminderAdditionalText.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
        reminderIntroText:
          description: Configuration level supplying reminderIntroText.
          enum:
            - SYSTEM
            - ORGANIZATION
            - APPOINTMENT_TYPE
          example: SYSTEM
          type: string
      required:
        - confirmationIntroText
        - confirmationAdditionalText
        - reminderIntroText
        - reminderAdditionalText
        - logoVisibility
      type: object
    PartnerEmailReminderConfiguredDto:
      additionalProperties: false
      properties:
        enabled:
          description: Configured switch, or null to inherit.
          nullable: true
          type: boolean
        leadMinutes:
          description: Configured lead time in minutes, or null to inherit.
          maximum: 43200
          minimum: 60
          nullable: true
          type: integer
      required:
        - enabled
        - leadMinutes
      type: object
    PartnerEmailReminderInheritedDto:
      additionalProperties: false
      properties:
        enabled:
          description: Resolved value inherited by the current configuration level.
          example: false
          type: boolean
        leadMinutes:
          description: Resolved lead time inherited by the current configuration level.
          example: 1440
          maximum: 43200
          minimum: 60
          type: integer
      required:
        - enabled
        - leadMinutes
      type: object
    PartnerIntakeFieldsResponseDto:
      additionalProperties: false
      properties:
        appointmentTypeId:
          description: Appointment type identifier.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          format: uuid
          type: string
        customIntakeFields:
          description: Complete ordered custom-field array. Empty clears fields. At most 61,440 UTF-8 bytes of canonical normalized JSON; unrelated intakeConfig properties are preserved.
          items:
            $ref: "#/components/schemas/AppointmentTypeIntakeFieldDto"
          maxItems: 30
          type: array
        revision:
          description: Opaque base64url revision of normalized custom fields. Return the latest read value unchanged; stale revisions produce 409. It is not a credential and does not describe the whole appointment type.
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
      required:
        - appointmentTypeId
        - customIntakeFields
        - revision
      type: object
    PartnerLoginLinkDto:
      properties:
        expiresAt:
          description: Token expiry (120 seconds after issuance).
          example: 2026-07-21T09:17:00.000Z
          format: date-time
          type: string
        loginUrl:
          description: One-time login URL for the pharmacy backoffice. The token is carried exclusively in the URL fragment (#token=...), is valid for 120 seconds, single use, and is shown exactly once in this response - it is never retrievable again and must not be cached or logged.
          example: https://beispiel-apotheke-4711.sandbox.arztkonsultation.io/app/magic-login#token=<OPAQUE_ONE_TIME_TOKEN>
          readOnly: true
          type: string
          x-akflow-one-time-credential: true
      required:
        - loginUrl
        - expiresAt
      type: object
    PartnerOffboardingRequestedDto:
      properties:
        offboardingRequestId:
          description: Offboarding request identifier.
          example: c0d13fd1-f37a-4537-9841-4d4ee0e3f6b8
          format: uuid
          type: string
        status:
          description: "Offboarding status. Since 2026-07-29 the partner request itself executes the deactivation: the request starts as EXECUTING (never PENDING_REVIEW), COMPLETED/COMPLETED_WITH_ERRORS once the tenant is closed, BLOCKED when cancellation work got stuck (audited admin intervention). PENDING_REVIEW, REJECTED and CONFIRMED only appear on legacy requests created before 2026-07-29 under the former admin-confirmation flow."
          enum:
            - PENDING_REVIEW
            - REJECTED
            - CANCELLED
            - EXECUTING
            - BLOCKED
            - COMPLETED
            - COMPLETED_WITH_ERRORS
            - CONFIRMED
          example: EXECUTING
          type: string
      required:
        - offboardingRequestId
        - status
      type: object
    PartnerOrganizationEmailMessageSettingsDto:
      additionalProperties: false
      properties:
        configured:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveEmailMessageSettingsDto"
        inheritedFrom:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsInheritedDto"
        organizationId:
          description: Scoped pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Opaque SHA-256 base64url revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
        sources:
          $ref: "#/components/schemas/PartnerEmailMessageSettingsSourcesDto"
      required:
        - consumerId
        - organizationId
        - configured
        - inheritedFrom
        - effective
        - sources
        - revision
      type: object
    PartnerOrganizationEmailReminderDto:
      additionalProperties: false
      properties:
        configured:
          $ref: "#/components/schemas/PartnerEmailReminderConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveEmailReminderDto"
        inheritedFrom:
          $ref: "#/components/schemas/PartnerEmailReminderInheritedDto"
        organizationId:
          description: Scoped pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-17T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - consumerId
        - organizationId
        - configured
        - inheritedFrom
        - effective
        - revision
      type: object
    PartnerOrganizationSchedulingPolicyDto:
      additionalProperties: false
      properties:
        configured:
          $ref: "#/components/schemas/PartnerSchedulingPolicyConfiguredDto"
        effective:
          $ref: "#/components/schemas/PartnerSchedulingPolicyEffectiveDto"
        organizationId:
          description: Scoped organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
      required:
        - organizationId
        - configured
        - effective
      type: object
    PartnerOrganizationSmsConfirmationConfiguredDto:
      additionalProperties: false
      properties:
        enabled:
          description: Organization-level SMS confirmation switch.
          example: true
          type: boolean
        text:
          description: Configured normalized GSM-7 SMS text, or null to use the safe system template.
          maxLength: 160
          nullable: true
          type: string
      required:
        - enabled
        - text
      type: object
    PartnerOrganizationSmsConfirmationDto:
      additionalProperties: false
      properties:
        configured:
          $ref: "#/components/schemas/PartnerOrganizationSmsConfirmationConfiguredDto"
        consumerId:
          description: Consumer derived from the authenticated scope.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        effective:
          $ref: "#/components/schemas/PartnerEffectiveSmsConfirmationDto"
        organizationId:
          description: Scoped pharmacy organization identifier.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-16T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - consumerId
        - organizationId
        - configured
        - effective
        - revision
      type: object
    PartnerPharmacyClaimDto:
      properties:
        consumerId:
          description: akflow tenant identifier.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        origin:
          description: The tenant originated in the partner console before this claim.
          enum:
            - CONSOLE
          example: CONSOLE
          type: string
        partner:
          description: Partner channel identifier derived from the caller's control.
          enum:
            - gedisa
            - medivise
          example: gedisa
          type: string
        partnerOrgId:
          description: Assigned partner-controlled pharmacy identifier.
          example: pharmacy-4711
          type: string
      required:
        - consumerId
        - partner
        - partnerOrgId
        - origin
      type: object
    PartnerPharmacyDirectoryEntryDto:
      additionalProperties: false
      properties:
        consumerId:
          format: uuid
          type: string
        name:
          description: Pharmacy display name.
          example: Beispiel-Apotheke
          type: string
        organizationId:
          format: uuid
          nullable: true
          type: string
        origin:
          description: Channel through which the pharmacy entered the partner directory.
          enum:
            - S2S
            - CONSOLE
          example: S2S
          type: string
        partnerOrgId:
          nullable: true
          type: string
        pharmacyLogin:
          $ref: "#/components/schemas/PharmacyLoginProjectionDto"
        slug:
          description: Tenant slug.
          example: beispiel-apotheke-4711
          type: string
        status:
          description: Derived tenant lifecycle and provisioning status.
          enum:
            - ACTIVE
            - PENDING
            - OFFBOARDED
          example: ACTIVE
          type: string
      required:
        - consumerId
        - organizationId
        - partnerOrgId
        - origin
        - slug
        - name
        - status
      type: object
    PartnerPharmacyDirectoryResponseDto:
      additionalProperties: false
      properties:
        items:
          description: Pharmacies visible to the authenticated partner control.
          items:
            $ref: "#/components/schemas/PartnerPharmacyDirectoryEntryDto"
          type: array
        page:
          description: Current 1-based page.
          example: 1
          type: integer
        pageSize:
          description: Applied page size.
          example: 25
          type: integer
        total:
          description: Total number of matching pharmacies.
          example: 1
          type: integer
      required:
        - items
        - total
        - page
        - pageSize
      type: object
    PartnerPharmacyMasterDataDto:
      additionalProperties: false
      properties:
        city:
          maxLength: 120
          minLength: 1
          type: string
        complete:
          type: boolean
        consumerId:
          format: uuid
          type: string
        country:
          pattern: ^[A-Z]{2}$
          type: string
        email:
          format: email
          maxLength: 200
          type: string
        imprintPath:
          enum:
            - /impressum
          type: string
        legalName:
          maxLength: 200
          minLength: 1
          type: string
        organizationId:
          format: uuid
          type: string
        phone:
          maxLength: 40
          minLength: 3
          type: string
        postalCode:
          maxLength: 20
          minLength: 1
          type: string
        street:
          maxLength: 200
          minLength: 1
          type: string
      required:
        - consumerId
        - organizationId
        - legalName
        - street
        - postalCode
        - city
        - country
        - phone
        - email
        - complete
        - imprintPath
      type: object
    PartnerPharmacyRegistrationDto:
      properties:
        companyId:
          description: akflow organization identifier of the pharmacy (company_id in webhook payloads).
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        consumerId:
          description: akflow tenant identifier.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          format: uuid
          type: string
        partner:
          description: Partner channel identifier.
          example: gedisa
          type: string
          x-extensible-enum:
            - gedisa
            - medivise
        partnerOrgId:
          description: Partner-controlled pharmacy identifier.
          example: pharmacy-4711
          type: string
        slug:
          description: Tenant slug.
          example: beispiel-apotheke-4711
          type: string
        ssoProvisioning:
          description: SSO/IdP provisioning state for the pharmacy realm.
          enum:
            - PENDING
            - READY
            - FAILED
          example: PENDING
          type: string
        status:
          description: Tenant lifecycle status. The tenant API key becomes usable once the status reaches ACTIVE (asynchronous provisioning).
          enum:
            - PROVISIONING_PENDING
            - ACTIVE
            - PROVISIONING_FAILED
            - DEACTIVATED
          example: PROVISIONING_PENDING
          type: string
        tenantApiKey:
          description: Tenant-scoped API key, returned exactly once in the 201 creation response. Store it securely; it cannot be retrieved again.
          properties:
            apiKey:
              description: The API key secret (shown once).
              example: <ONE_TIME_API_KEY>
              readOnly: true
              type: string
              x-akflow-one-time-credential: true
            keyId:
              description: Key identifier.
              example: ak_test_ab12cd34
              type: string
            scopes:
              description: Tenant key scopes.
              example:
                - appointments:read
                - appointments:cancel
                - rooms:read
                - rooms:write
              items:
                type: string
              type: array
          type: object
      type: object
    PartnerPharmacyRoomAvailabilityRuleDto:
      properties:
        dayOfWeek:
          description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
          example: 1
          maximum: 6
          minimum: 0
          type: integer
        endTime:
          description: End time in exact HH:mm format and strictly later than startTime. 24:00 is accepted as the end of the local day.
          example: 12:00
          pattern: ^(([01]\d|2[0-3]):[0-5]\d|24:00)$
          type: string
        startTime:
          description: Start time in exact HH:mm format. 24:00 is allowed only as endTime because endTime must be strictly later than startTime.
          example: 08:00
          pattern: ^(([01]\d|2[0-3]):[0-5]\d|24:00)$
          type: string
        timezone:
          description: Optional canonical IANA timezone accepted by the runtime, such as Europe/Berlin.
          example: Europe/Berlin
          type: string
        validFrom:
          description: Optional first local date on which this room rule is valid.
          example: 2026-06-01
          format: date
          nullable: true
          type: string
        validUntil:
          description: Optional inclusive last local date on which this room rule is valid. When validFrom is supplied, validUntil must be on or after validFrom. Null means open-ended.
          example: 2026-12-31
          format: date
          nullable: true
          type: string
      required:
        - dayOfWeek
        - startTime
        - endTime
      type: object
    PartnerPharmacyRoomDto:
      additionalProperties: false
      properties:
        availabilityRules:
          description: Active room availability rules.
          items:
            $ref: "#/components/schemas/PartnerRoomAvailabilityRuleDto"
          type: array
        id:
          description: Pharmacy room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          format: uuid
          type: string
        isActive:
          description: Whether the room is active.
          example: true
          type: boolean
        name:
          description: Room display name.
          example: Beratungsraum 1
          type: string
      required:
        - id
        - name
        - isActive
        - availabilityRules
      type: object
    PartnerPharmacyRoomsResponseDto:
      properties:
        pharmacy:
          description: Pharmacy organization owning the rooms.
          properties:
            id:
              description: Pharmacy organization identifier.
              example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
              format: uuid
              type: string
            name:
              description: Pharmacy organization display name.
              example: Kaiser Apotheke
              type: string
          type: object
        rooms:
          description: Pharmacy rooms sorted by active state and display name.
          items:
            $ref: "#/components/schemas/PartnerPharmacyRoomDto"
          type: array
      required:
        - pharmacy
        - rooms
      type: object
    PartnerRegistrationConflictResponse:
      description: Compatible 409 response envelope. It accepts both the original Nest ApiError shape and the domain {message, code} shape without oneOf overlap ambiguity.
      properties:
        code:
          description: Optional stable partner-registration conflict code.
          enum:
            - CONSUMER_SLUG_TAKEN
            - CONSUMER_SLUG_RESERVED
            - CONSUMER_SLUG_TAKEN_BY_PARTNER
            - PARTNER_LINK_UNCLAIMED
            - PARTNER_ACCESS_INVARIANT_VIOLATION
            - PARTNER_REGISTRATION_LIFECYCLE_INVALID
            - XUND_SHARED_CREDENTIAL_MISSING
            - XUND_SHARED_CREDENTIAL_INACTIVE
            - XUND_SHARED_CREDENTIAL_UNUSABLE
            - XUND_SHARED_CREDENTIAL_AMBIGUOUS
          example: PARTNER_ACCESS_INVARIANT_VIOLATION
          type: string
        correlationId:
          description: Optional request correlation ID when supplied by the client.
          example: local-smoke-001
          type: string
        error:
          description: HTTP error class.
          example: Conflict
          type: string
        message:
          description: Human-readable conflict message. Branch on code when it is present, never on this text.
          example: Conflict
          type: string
        statusCode:
          description: HTTP status code.
          example: 409
          type: integer
      required:
        - message
      type: object
    PartnerRoomAvailabilityRuleDto:
      additionalProperties: false
      properties:
        dayOfWeek:
          description: "Weekday in JS/cron convention: 0 Sunday, 6 Saturday."
          example: 1
          maximum: 6
          minimum: 0
          type: integer
        endTime:
          description: End time in HH:mm.
          example: 12:00
          type: string
        id:
          description: Room availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          format: uuid
          type: string
        isActive:
          description: Whether the rule is active.
          example: true
          type: boolean
        startTime:
          description: Start time in HH:mm.
          example: 08:00
          type: string
        timezone:
          description: IANA timezone.
          example: Europe/Berlin
          type: string
        validFrom:
          description: First local date on which this rule is valid.
          example: 2026-06-01
          format: date
          nullable: true
          type: string
        validUntil:
          description: Last local date on which this rule is valid.
          example: null
          format: date
          nullable: true
          type: string
      required:
        - id
        - dayOfWeek
        - startTime
        - endTime
        - timezone
        - validFrom
        - validUntil
        - isActive
      type: object
    PartnerRoomConflictError:
      additionalProperties: false
      description: Room mutation conflict caused by a duplicate name or an inactive room.
      properties:
        code:
          description: Stable room conflict code.
          enum:
            - ROOM_NAME_CONFLICT
            - PHARMACY_ROOM_INACTIVE
          example: PHARMACY_ROOM_INACTIVE
          type: string
        error:
          description: HTTP error class.
          example: Conflict
          type: string
        message:
          description: Human-readable room conflict message. Branch on code, never on this text.
          example: Pharmacy room is inactive
          type: string
        statusCode:
          description: HTTP status code.
          example: 409
          type: integer
      required:
        - statusCode
        - message
        - error
        - code
      type: object
    PartnerRoomNotFoundError:
      additionalProperties: false
      description: Tenant-scoped pharmacy organization, room or room-rule lookup rejection.
      properties:
        code:
          description: Stable room lookup code.
          enum:
            - PHARMACY_ORGANIZATION_NOT_FOUND
            - PHARMACY_ROOM_NOT_FOUND
            - ROOM_AVAILABILITY_RULE_NOT_FOUND
          example: PHARMACY_ROOM_NOT_FOUND
          type: string
        error:
          description: HTTP error class.
          example: Not Found
          type: string
        message:
          description: Human-readable room lookup message. Branch on code, never on this text.
          example: Pharmacy room not found
          type: string
        statusCode:
          description: HTTP status code.
          example: 404
          type: integer
      required:
        - statusCode
        - message
        - error
        - code
      type: object
    PartnerRoomValidationError:
      additionalProperties: false
      description: Domain-level validation rejection from the shared pharmacy-room mutation core.
      properties:
        code:
          description: Stable room validation code.
          enum:
            - ROOM_NAME_REQUIRED
            - ROOM_UPDATE_EMPTY
          example: ROOM_UPDATE_EMPTY
          type: string
        error:
          description: HTTP error class.
          example: Bad Request
          type: string
        message:
          description: ValidationPipe messages are arrays; domain-level room validation uses one human-readable string. Branch on code when it is present, never on this text.
          oneOf:
            - example: Room update must contain a supported change
              type: string
            - example:
                - name must be shorter than or equal to 120 characters
              items:
                type: string
              type: array
        statusCode:
          description: HTTP status code.
          example: 400
          type: integer
      required:
        - statusCode
        - message
        - error
      type: object
    PartnerSchedulingPolicyConfiguredDto:
      additionalProperties: false
      properties:
        cancellationDeadlineHours:
          description: Cancellation deadline applied to newly evaluated booking decisions, in hours. Null selects inheritance; 0 is an explicit configured value.
          example: null
          maximum: 8760
          minimum: 0
          nullable: true
          type: integer
        followUpMinutes:
          description: Follow-up time reserved after a newly evaluated booking, in minutes. Null selects inheritance; 0 is an explicit configured value.
          example: null
          maximum: 480
          minimum: 0
          nullable: true
          type: integer
        minLeadMinutes:
          description: Minimum lead time required when a new booking decision is evaluated, in minutes. Null selects inheritance; 0 is an explicit configured value.
          example: null
          maximum: 43200
          minimum: 0
          nullable: true
          type: integer
        prepMinutes:
          description: Preparation time reserved before a newly evaluated booking, in minutes. Null selects inheritance; 0 is an explicit configured value.
          example: null
          maximum: 480
          minimum: 0
          nullable: true
          type: integer
      required:
        - prepMinutes
        - followUpMinutes
        - minLeadMinutes
        - cancellationDeadlineHours
      type: object
    PartnerSchedulingPolicyEffectiveDto:
      additionalProperties: false
      properties:
        cancellationDeadlineHours:
          description: Cancellation deadline applied to newly evaluated booking decisions, in hours.
          example: 0
          maximum: 8760
          minimum: 0
          type: integer
        followUpMinutes:
          description: Follow-up time reserved after a newly evaluated booking, in minutes.
          example: 0
          maximum: 480
          minimum: 0
          type: integer
        minLeadMinutes:
          description: Minimum lead time required when a new booking decision is evaluated, in minutes.
          example: 0
          maximum: 43200
          minimum: 0
          type: integer
        prepMinutes:
          description: Preparation time reserved before a newly evaluated booking, in minutes.
          example: 0
          maximum: 480
          minimum: 0
          type: integer
      required:
        - prepMinutes
        - followUpMinutes
        - minLeadMinutes
        - cancellationDeadlineHours
      type: object
    PartnerSmedConfigDto:
      additionalProperties: false
      properties:
        consumerId:
          format: uuid
          type: string
        organizationId:
          format: uuid
          type: string
        smedId:
          description: Optional non-secret SMED identifier. Null means that no SMED assignment is configured.
          example: SMED-42
          maxLength: 128
          nullable: true
          pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
          type: string
      required:
        - consumerId
        - organizationId
        - smedId
      type: object
    PartnerWebhookDto:
      properties:
        createdAt:
          description: Creation timestamp.
          example: 2026-07-03T10:00:00.000Z
          format: date-time
          type: string
        events:
          description: Subscribed partner events.
          example:
            - appointment.created
            - appointment.cancelled
          items:
            type: string
          type: array
        id:
          description: Webhook identifier.
          example: c0d13fd1-f37a-4537-9841-4d4ee0e3f6b8
          format: uuid
          type: string
        isActive:
          description: Whether the webhook is active.
          example: true
          type: boolean
        secret:
          description: Signing secret, returned exactly once in the creation response. Verify x-akflow-signature = sha256 HMAC over `${x-akflow-timestamp}.${body}`.
          example: <ONE_TIME_SIGNING_SECRET>
          readOnly: true
          type: string
          x-akflow-one-time-credential: true
        url:
          description: Receiver URL.
          example: https://webhooks.partner.example/akflow
          type: string
      type: object
    PartnerWebhooksResponseDto:
      properties:
        webhooks:
          description: Configured webhooks (never contain secret material).
          items:
            $ref: "#/components/schemas/PartnerWebhookDto"
          type: array
      type: object
    PartnerWebhookTestEnqueuedDto:
      properties:
        enqueued:
          description: Whether the test delivery was enqueued.
          example: true
          type: boolean
        eventId:
          description: Outbox event identifier.
          example: c0d13fd1-f37a-4537-9841-4d4ee0e3f6b8
          format: uuid
          type: string
      required:
        - enqueued
        - eventId
      type: object
    PatchPartnerEmailMessageSettingsDto:
      additionalProperties: false
      anyOf:
        - required:
            - confirmationIntroText
        - required:
            - confirmationAdditionalText
        - required:
            - reminderIntroText
        - required:
            - reminderAdditionalText
        - required:
            - logoVisibility
      properties:
        confirmationAdditionalText:
          description: Additional confirmation text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        confirmationIntroText:
          description: Confirmation introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        logoVisibility:
          description: Configured logo visibility, or null to inherit.
          enum:
            - SHOW
            - HIDE
          nullable: true
          type: string
        reason:
          description: Required trimmed PHI-free justification. The reason is never stored, returned or logged; audit records reasonProvided only.
          example: E-Mail-Texte abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        reminderAdditionalText:
          description: Additional reminder text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        reminderIntroText:
          description: Reminder introduction text. Null selects inheritance. Normalized text is additionally limited to 8 lines and 4096 UTF-8 bytes and accepts only the documented placeholders.
          maxLength: 1000
          minLength: 1
          nullable: true
          type: string
        revision:
          description: Opaque SHA-256 base64url revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
      required:
        - revision
        - reason
      type: object
    PharmacyLoginProjectionDto:
      additionalProperties: false
      properties:
        accessAvailable:
          description: Whether realm reconciliation is ACTIVE; not an actor capability grant.
          example: true
          type: boolean
        effectiveMode:
          description: Effective pharmacy realm login mode; never the requested mode.
          enum:
            - NATIVE_MFA
            - MAGIC_LINK_ONLY
          example: NATIVE_MFA
          type: string
        organizationId:
          description: Exact unique active PHARMACY organization bound to this visible consumer.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          format: uuid
          type: string
        reconciliationStatus:
          description: Realm login reconciliation state.
          enum:
            - ACTIVE
            - PREPARING
            - FAILED
          example: ACTIVE
          type: string
      required:
        - organizationId
        - effectiveMode
        - reconciliationStatus
        - accessAvailable
      type: object
    PreviewPartnerSettingsCopyDto:
      additionalProperties: false
      properties:
        appointmentTypePairs:
          description: Explicit appointment-type pairs. Source IDs may repeat; target IDs must be unique.
          items:
            $ref: "#/components/schemas/SettingsCopyAppointmentTypePairDto"
          maxItems: 20
          minItems: 0
          type: array
        sourcePartnerOrgId:
          description: Partner-owned source pharmacy selector.
          example: synthetic-source-01
          pattern: ^[A-Za-z0-9._:-]{1,64}$
          type: string
        strategy:
          default: FAIL_ON_CONFLICT
          description: Conflict strategy. OVERWRITE_CONFLICTS requires a fresh Preview generated for that strategy.
          enum:
            - FAIL_ON_CONFLICT
            - OVERWRITE_CONFLICTS
          example: FAIL_ON_CONFLICT
          type: string
        targetPartnerOrgId:
          description: Partner-owned target pharmacy selector.
          example: synthetic-target-01
          pattern: ^[A-Za-z0-9._:-]{1,64}$
          type: string
      required:
        - sourcePartnerOrgId
        - targetPartnerOrgId
      type: object
    ReplacePartnerIntakeFieldsDto:
      additionalProperties: false
      properties:
        fields:
          description: Complete ordered custom-field array. Empty clears fields. At most 61,440 UTF-8 bytes of canonical normalized JSON; unrelated intakeConfig properties are preserved.
          items:
            $ref: "#/components/schemas/AppointmentTypeIntakeFieldInputDto"
          maxItems: 30
          type: array
        reason:
          description: "Required PHI-free justification: 5–500 Unicode code points after trimming. Wire superset: OpenAPI 3 cannot express trim-before-length; the runtime enforces normalized limits, while the complete raw PATCH body is limited to 65,536 bytes. Never persisted, returned or logged; audit records reasonProvided only."
          minLength: 5
          pattern: \S
          type: string
        revision:
          description: Opaque base64url revision of normalized custom fields. Return the latest read value unchanged; stale revisions produce 409. It is not a credential and does not describe the whole appointment type.
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
      required:
        - revision
        - fields
        - reason
      type: object
    SettingsCopyApplyResultDto:
      additionalProperties: false
      properties:
        applied:
          enum:
            - true
          example: true
          type: boolean
        conflictCount:
          description: Detected conflict count.
          example: 0
          type: integer
        copyCount:
          description: Copied field count.
          example: 1
          type: integer
        noSourceValueCount:
          description: Fields without a configured source value.
          example: 0
          type: integer
        overwrittenConflictCount:
          description: Conflicts overwritten by the selected strategy.
          example: 0
          type: integer
        unchangedCount:
          description: Unchanged field count.
          example: 0
          type: integer
        writtenFields:
          description: Sorted unique names of fields written; no values are returned.
          items:
            enum:
              - prepMinutes
              - followUpMinutes
              - minLeadMinutes
              - cancellationDeadlineHours
              - confirmationAdditionalText
              - confirmationIntroText
              - logoVisibility
              - reminderAdditionalText
              - reminderIntroText
              - customIntakeFields
            type: string
          type: array
          uniqueItems: true
      required:
        - applied
        - copyCount
        - unchangedCount
        - conflictCount
        - noSourceValueCount
        - overwrittenConflictCount
        - writtenFields
      type: object
    SettingsCopyAppointmentTypeFieldPreviewDto:
      additionalProperties: false
      properties:
        field:
          description: Copyable field name; no configured value is returned.
          enum:
            - prepMinutes
            - followUpMinutes
            - minLeadMinutes
            - cancellationDeadlineHours
            - confirmationAdditionalText
            - confirmationIntroText
            - logoVisibility
            - reminderAdditionalText
            - reminderIntroText
            - customIntakeFields
          example: prepMinutes
          type: string
        status:
          description: Value-free comparison status.
          enum:
            - COPY
            - UNCHANGED
            - CONFLICT
            - NO_SOURCE_VALUE
          example: COPY
          type: string
      required:
        - field
        - status
      type: object
    SettingsCopyAppointmentTypePairDto:
      additionalProperties: false
      properties:
        sourceAppointmentTypeId:
          description: Active appointment type in the source pharmacy.
          example: 10000000-0000-4000-8000-000000000005
          format: uuid
          type: string
        targetAppointmentTypeId:
          description: Active appointment type in the target pharmacy. Must be unique within the request.
          example: 10000000-0000-4000-8000-000000000006
          format: uuid
          type: string
      required:
        - sourceAppointmentTypeId
        - targetAppointmentTypeId
      type: object
    SettingsCopyAppointmentTypePairPreviewDto:
      additionalProperties: false
      properties:
        fields:
          description: Value-free field statuses.
          items:
            $ref: "#/components/schemas/SettingsCopyAppointmentTypeFieldPreviewDto"
          maxItems: 10
          minItems: 10
          type: array
        sourceAppointmentTypeId:
          description: Source appointment-type identifier.
          example: 10000000-0000-4000-8000-000000000005
          format: uuid
          type: string
        targetAppointmentTypeId:
          description: Target appointment-type identifier.
          example: 10000000-0000-4000-8000-000000000006
          format: uuid
          type: string
      required:
        - sourceAppointmentTypeId
        - targetAppointmentTypeId
        - fields
      type: object
    SettingsCopyCountsDto:
      additionalProperties: false
      properties:
        CONFLICT:
          description: CONFLICT field count.
          example: 0
          type: integer
        COPY:
          description: COPY field count.
          example: 0
          type: integer
        NO_SOURCE_VALUE:
          description: NO_SOURCE_VALUE field count.
          example: 0
          type: integer
        UNCHANGED:
          description: UNCHANGED field count.
          example: 0
          type: integer
      required:
        - COPY
        - UNCHANGED
        - CONFLICT
        - NO_SOURCE_VALUE
      type: object
    SettingsCopyErrorDto:
      additionalProperties: false
      properties:
        code:
          description: Stable value-free domain error code.
          enum:
            - SETTINGS_COPY_INVALID
            - SETTINGS_COPY_NOT_FOUND
            - SETTINGS_COPY_CHANGED
            - SETTINGS_COPY_CONFLICT
            - IDEMPOTENCY_KEY_REUSED
          example: SETTINGS_COPY_CHANGED
          type: string
        error:
          description: HTTP error class.
          enum:
            - Bad Request
            - Not Found
            - Conflict
          example: Conflict
          type: string
        message:
          description: Value-free domain error message.
          enum:
            - Settings copy request is invalid
            - Settings copy target not found
            - Settings copy changed
            - Settings copy conflict
            - Idempotency key was already used
          example: Settings copy changed
          type: string
        statusCode:
          enum:
            - 400
            - 404
            - 409
          type: integer
      required:
        - statusCode
        - error
        - code
        - message
      type: object
    SettingsCopyOrganizationFieldPreviewDto:
      additionalProperties: false
      properties:
        field:
          description: Copyable field name; no configured value is returned.
          enum:
            - prepMinutes
            - followUpMinutes
            - minLeadMinutes
            - cancellationDeadlineHours
            - confirmationAdditionalText
            - confirmationIntroText
            - logoVisibility
            - reminderAdditionalText
            - reminderIntroText
          example: cancellationDeadlineHours
          type: string
        status:
          description: Value-free comparison status.
          enum:
            - COPY
            - UNCHANGED
            - CONFLICT
            - NO_SOURCE_VALUE
          example: COPY
          type: string
      required:
        - field
        - status
      type: object
    SettingsCopyPreviewDto:
      additionalProperties: false
      properties:
        appointmentTypePairs:
          description: Canonical target-then-source ordered pair previews.
          items:
            $ref: "#/components/schemas/SettingsCopyAppointmentTypePairPreviewDto"
          maxItems: 20
          minItems: 0
          type: array
        counts:
          $ref: "#/components/schemas/SettingsCopyCountsDto"
        organizationFields:
          description: Value-free organization field statuses.
          items:
            $ref: "#/components/schemas/SettingsCopyOrganizationFieldPreviewDto"
          maxItems: 9
          minItems: 9
          type: array
        previewRevision:
          description: Opaque value-free revision returned by Preview. It is bound to selectors, pairs, strategy and current copyable state.
          example: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          maxLength: 43
          minLength: 43
          pattern: ^[A-Za-z0-9_-]{43}$
          type: string
        strategy:
          description: Conflict strategy. OVERWRITE_CONFLICTS requires a fresh Preview generated for that strategy.
          enum:
            - FAIL_ON_CONFLICT
            - OVERWRITE_CONFLICTS
          example: FAIL_ON_CONFLICT
          type: string
      required:
        - strategy
        - previewRevision
        - organizationFields
        - appointmentTypePairs
        - counts
      type: object
    UpdatePartnerAdditionalConfirmationRecipientsDto:
      additionalProperties: false
      properties:
        reason:
          maxLength: 500
          minLength: 5
          type: string
        recipients:
          items:
            format: email
            maxLength: 254
            type: string
          maxItems: 5
          type: array
      required:
        - recipients
        - reason
      type: object
    UpdatePartnerAppointmentTypeEmailReminderDto:
      additionalProperties: false
      properties:
        enabled:
          description: Optional explicit switch. Null restores inheritance; omission leaves the field unchanged.
          nullable: true
          type: boolean
        leadMinutes:
          description: Optional lead time in minutes. Null restores inheritance; omission leaves the field unchanged.
          maximum: 43200
          minimum: 60
          nullable: true
          type: integer
        reason:
          description: Required trimmed PHI-free justification. The reason is never stored, returned or logged; audit records reasonProvided only.
          example: E-Mail-Erinnerung abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-17T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - revision
        - reason
      type: object
    UpdatePartnerAppointmentTypeSmsConfirmationDto:
      additionalProperties: false
      properties:
        enabled:
          description: Optional explicit switch. Null restores organization inheritance; omission leaves the field unchanged.
          nullable: true
          type: boolean
        reason:
          description: Required trimmed PHI-free justification. The reason is never stored, returned or logged; audit records reasonProvided only.
          example: SMS-Konfiguration abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-16T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
        text:
          description: Optional normalized single-segment GSM-7 text. Null restores inheritance; omission leaves the field unchanged. Runtime validation counts extension characters as two septets and rejects control characters, placeholders, URLs, query fragments and credential syntax.
          maxLength: 160
          nullable: true
          type: string
      required:
        - revision
        - reason
      type: object
    UpdatePartnerAvailabilityRuleDto:
      properties:
        dayOfWeek:
          description: "Optional replacement weekday in JS/cron convention: 0 Sunday, 6 Saturday."
          example: 1
          maximum: 6
          minimum: 0
          type: integer
        endTime:
          description: Optional replacement end time in HH:mm.
          example: 13:00
          type: string
        generateFrom:
          description: Optional first date for slot regeneration. Must be sent together with generateTo.
          example: 2026-06-01
          format: date
          type: string
        generateTo:
          description: Optional last date for slot regeneration. Must be sent together with generateFrom.
          example: 2026-06-30
          format: date
          type: string
        slotDuration:
          description: Optional replacement slot duration in minutes.
          example: 30
          type: integer
        specialtySlug:
          description: Optional replacement specialty slug. The provider must already have this specialty.
          example: adipositas
          type: string
        startTime:
          description: Optional replacement start time in HH:mm.
          example: 10:00
          type: string
        timezone:
          description: Optional replacement IANA timezone.
          example: Europe/Berlin
          type: string
      type: object
    UpdatePartnerKimAddressDto:
      additionalProperties: false
      properties:
        kimAddress:
          description: Omit to keep the current value, send null to remove it, or send a valid .kim.telematik address.
          example: team@praxis.kim.telematik
          oneOf:
            - format: email
              maxLength: 254
              minLength: 1
              pattern: ^[^\u0000-\u001f\u007f-\u009f]+@[^\s@]+\.[kK][iI][mM]\.[tT][eE][lL][eE][mM][aA][tT][iI][kK]$
              type: string
            - enum:
                - null
              nullable: true
              type: string
        reason:
          description: Required trimmed PHI-free audit justification. The reason and KIM address are never stored in audit metadata.
          maxLength: 500
          minLength: 5
          type: string
      required:
        - reason
      type: object
    UpdatePartnerOrganizationEmailReminderDto:
      additionalProperties: false
      properties:
        enabled:
          description: Optional explicit switch. Null restores inheritance; omission leaves the field unchanged.
          nullable: true
          type: boolean
        leadMinutes:
          description: Optional lead time in minutes. Null restores inheritance; omission leaves the field unchanged.
          maximum: 43200
          minimum: 60
          nullable: true
          type: integer
        reason:
          description: Required trimmed PHI-free justification. The reason is never stored, returned or logged; audit records reasonProvided only.
          example: E-Mail-Erinnerung abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-17T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
      required:
        - revision
        - reason
      type: object
    UpdatePartnerOrganizationSmsConfirmationDto:
      additionalProperties: false
      properties:
        enabled:
          description: Optional organization switch; omission leaves the field unchanged.
          type: boolean
        reason:
          description: Required trimmed PHI-free justification. The reason is never stored, returned or logged; audit records reasonProvided only.
          example: SMS-Konfiguration abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
        revision:
          description: Expected revision from the latest read. A stale value returns 409 and must be reconciled before retrying.
          example: 2026-09-16T08:30:00.000Z
          format: date-time
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$
          type: string
        text:
          description: Optional normalized single-segment GSM-7 text. Null restores inheritance; omission leaves the field unchanged. Runtime validation counts extension characters as two septets and rejects control characters, placeholders, URLs, query fragments and credential syntax.
          maxLength: 160
          nullable: true
          type: string
      required:
        - revision
        - reason
      type: object
    UpdatePartnerPharmacyMasterDataDto:
      additionalProperties: false
      properties:
        city:
          maxLength: 120
          minLength: 1
          type: string
        country:
          pattern: ^[A-Z]{2}$
          type: string
        email:
          format: email
          maxLength: 200
          type: string
        legalName:
          maxLength: 200
          minLength: 1
          type: string
        phone:
          maxLength: 40
          minLength: 3
          type: string
        postalCode:
          maxLength: 20
          minLength: 1
          type: string
        reason:
          description: "Required trimmed PHI-free audit justification. The reason is never stored; the audit records only reasonProvided: true."
          maxLength: 500
          minLength: 5
          type: string
        street:
          maxLength: 200
          minLength: 1
          type: string
      required:
        - legalName
        - street
        - postalCode
        - city
        - country
        - phone
        - email
        - reason
      type: object
    UpdatePartnerPharmacyRoomDto:
      properties:
        isActive:
          description: Optional active flag. Set false to hide the room from new scheduling.
          example: true
          type: boolean
        name:
          description: Optional updated room display name. Leading and trailing whitespace is removed; at least one non-whitespace character must remain.
          example: Beratungsraum 2
          maxLength: 120
          pattern: \S
          type: string
      type: object
    UpdatePartnerResourceModeDto:
      properties: {}
      type: object
    UpdatePartnerSchedulingPolicyWithReasonDto:
      additionalProperties: false
      properties:
        cancellationDeadlineHours:
          description: Cancellation deadline applied to newly evaluated booking decisions, in hours. When omitted (undefined at the DTO boundary), the field is unchanged; null selects inheritance; 0 is an explicit value.
          example: 0
          maximum: 8760
          minimum: 0
          nullable: true
          type: integer
        followUpMinutes:
          description: Follow-up time reserved after a newly evaluated booking, in minutes. When omitted (undefined at the DTO boundary), the field is unchanged; null selects inheritance; 0 is an explicit value.
          example: 0
          maximum: 480
          minimum: 0
          nullable: true
          type: integer
        minLeadMinutes:
          description: Minimum lead time required when a new booking decision is evaluated, in minutes. When omitted (undefined at the DTO boundary), the field is unchanged; null selects inheritance; 0 is an explicit value.
          example: 0
          maximum: 43200
          minimum: 0
          nullable: true
          type: integer
        prepMinutes:
          description: Preparation time reserved before a newly evaluated booking, in minutes. When omitted (undefined at the DTO boundary), the field is unchanged; null selects inheritance; 0 is an explicit value.
          example: 0
          maximum: 480
          minimum: 0
          nullable: true
          type: integer
        reason:
          description: "Required trimmed PHI-free audit justification. The reason is never stored; the audit records only reasonProvided: true."
          example: Terminvorlauf abgestimmt.
          maxLength: 500
          minLength: 5
          type: string
      required:
        - reason
      type: object
    UpdatePartnerSmedConfigDto:
      additionalProperties: false
      properties:
        reason:
          description: Required trimmed PHI-free audit justification. The reason and SMED identifier are not stored in audit metadata.
          maxLength: 500
          minLength: 5
          type: string
        smedId:
          description: Optional non-secret SMED identifier. Omit to keep the current value; null or blank input clears the assignment.
          example: SMED-42
          oneOf:
            - maxLength: 128
              pattern: ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
              type: string
            - maxLength: 128
              pattern: ^\s*$
              type: string
            - enum:
                - null
              nullable: true
              type: string
      required:
        - reason
      type: object
  securitySchemes:
    consumerApiKey:
      description: Consumer API key for S2S integrations.
      in: header
      name: X-API-Key
      type: apiKey
info:
  contact: {}
  description: Public server-to-server API for arztkonsultation integration partners.
  title: akflow Partner API
  version: 1.9.0
openapi: 3.0.0
paths:
  /api/v1/s2s/appointments:
    get:
      description: "Lists appointments for the required from/to local date range: tenant-local bookings of the authenticated pharmacy plus cross-consumer bookings that live in a doctor tenant and are correlated to this pharmacy via an ACTIVE partner appointment link (care-network bookings). PENDING or aborted correlations are never visible. The union is deduplicated and sorted by start time; specialty/provider/status filters apply to both sources. Responses are PHI-minimized and include scheduling metadata plus externalPatientRef, but not decrypted patient contact data."
      operationId: listPartnerAppointments
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Start date in YYYY-MM-DD format.
          example: 2026-06-01
          in: query
          name: from
          required: true
          schema:
            format: date
            type: string
        - description: End date in YYYY-MM-DD format.
          example: 2026-06-07
          in: query
          name: to
          required: true
          schema:
            format: date
            type: string
        - description: Filter or target a specific provider. Defaults to the authenticated provider when omitted.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: query
          name: providerId
          required: false
          schema:
            format: uuid
            type: string
        - description: Optional appointment status filter.
          example: CONFIRMED
          in: query
          name: status
          required: false
          schema:
            enum:
              - CONFIRMED
              - PENDING_PARTNER_CONFIRMATION
              - COMPLETED
              - NO_SHOW
              - CANCELLED
            type: string
        - description: Specialty slug, for example adipositas.
          example: adipositas
          in: query
          name: specialtySlug
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentsResponseDto"
          description: Appointments in the requested local date range.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner appointments
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/appointments/{appointmentId}:
    get:
      description: Reads one appointment by booking id or video sessionRef. Tenant-local bookings resolve directly; bookings in a doctor tenant resolve through the pharmacy's own ACTIVE partner appointment link. Ids without such a correlation - including bookings of other tenants and PENDING links - are uniformly hidden as 404.
      operationId: getPartnerAppointment
      parameters:
        - description: "Tenant-local appointment reference: either the Booking id (UUID) or the video call id (sessionRef) delivered in the appointment payload."
          example: 8cb6d8b8-a582-4cd2-8095-f60537a0d3dc
          in: path
          name: appointmentId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentDto"
          description: PHI-minimized appointment detail.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get partner appointment
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/appointments/{appointmentId}/cancel:
    post:
      description: Cancels an appointment using the required closed PHI-free reasonCode, releases its slot and room reservation, and emits a booking.cancelled outbox event. Cross-consumer bookings resolved via an ACTIVE partner appointment link are cancelled inside the doctor tenant (including the care-network release saga event); the partner cancellation deadline always comes from the DOCTOR consumer's organization config. Free-text reasons are rejected. Cancelling an already cancelled appointment is idempotent and returns 200 with the current state. Cancellations past the appointment start or past a configured partner cancellation deadline are rejected with 409 and code PARTNER_CANCELLATION_DEADLINE_PASSED. Send an Idempotency-Key header to make retries traceable in the audit trail.
      operationId: cancelPartnerAppointment
      parameters:
        - description: "Tenant-local appointment reference: either the Booking id (UUID) or the video call id (sessionRef) delivered in the appointment payload."
          example: 8cb6d8b8-a582-4cd2-8095-f60537a0d3dc
          in: path
          name: appointmentId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Optional idempotency key for safe retries of booking mutations.
          example: booking-create-2026-05-13-001
          in: header
          name: Idempotency-Key
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CancelPartnerAppointmentDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentDto"
          description: Cancelled PHI-minimized appointment detail.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Cancel partner appointment
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/bookings:
    post:
      description: Creates a booking for an available slot in the authenticated consumer tenant. Send Idempotency-Key for safe retries; repeated requests with the same key return the original booking result instead of creating duplicates.
      operationId: createBooking
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Optional idempotency key for safe retries of booking mutations.
          example: booking-create-2026-05-13-001
          in: header
          name: Idempotency-Key
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBookingDto"
        required: true
      responses:
        "201":
          description: Booking created or idempotently returned for the submitted slot.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create a booking
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/organizations:
    post:
      description: Creates an organization within the authenticated consumer tenant. Use this endpoint when an integration owns organization provisioning for an MVZ, clinic, or standalone practice.
      operationId: createOrganization
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrganizationDto"
        required: true
      responses:
        "201":
          description: Organization created for the authenticated consumer tenant.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create an organization
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies:
    get:
      description: Lists the pharmacies visible to the authenticated ACTIVE partner control (scope partners:register). The result is the union of registrations owned by this partner consumer and console-created pharmacies exposed through the control's active platform-partner grant. origin distinguishes S2S from CONSOLE; console-created pharmacies carry null partnerOrgId and organizationId until they are claimed. The optional pharmacyLogin projects the effective realm mode for a uniquely bound active PHARMACY, without changing those link fields; accessAvailable denotes ACTIVE reconciliation, not an actor capability. PENDING and OFFBOARDED entries omit the projection. Foreign, unclaimed and same-channel registrations owned elsewhere are excluded without revealing their existence.
      operationId: listPartnerPharmacies
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Optional derived pharmacy lifecycle and provisioning status filter.
          example: ACTIVE
          in: query
          name: status
          required: false
          schema:
            enum:
              - ACTIVE
              - PENDING
              - OFFBOARDED
            type: string
        - description: Optional case-insensitive search over the pharmacy tenant slug and name.
          example: apotheke
          in: query
          name: search
          required: false
          schema:
            maxLength: 100
            type: string
        - description: 1-based page number.
          example: 1
          in: query
          name: page
          required: false
          schema:
            minimum: 1
            type: integer
        - description: Page size (max 100).
          example: 25
          in: query
          name: pageSize
          required: false
          schema:
            maximum: 100
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyDirectoryResponseDto"
          description: Paginated partner pharmacy directory.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner pharmacies
      tags:
        - s2s
      x-akflow-publication: partner
    post:
      description: "Registers a pharmacy as its own akflow tenant under the authenticated partner platform key (scope partners:register). Requires an ACTIVE PartnerControl for the calling consumer (403 with code PARTNER_CONTROL_REQUIRED otherwise). Idempotent per (partner, partnerOrgId): a repeated registration returns 200 with the existing registration and never a second tenant or API key - but only for registrations owned by the calling partner consumer; a partnerOrgId registered by another partner consumer answers 404 without confirming its existence. The 201 creation response contains the tenant-scoped API key exactly once. The booking page is published automatically during registration. Tenant activation and realm provisioning run inline with the request (direct activation): the response normally already reports status ACTIVE. Only when the inline provisioning fails transiently does the response report PROVISIONING_PENDING and activation completes asynchronously - poll the GET endpoint until status is ACTIVE in that case."
      operationId: createPartnerPharmacy
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerPharmacyDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRegistrationDto"
          description: Pharmacy tenant registered; includes the one-time tenant API key. Backoffice access is issued exclusively via the login-links endpoint (no owner invite in the response).
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRegistrationConflictResponse"
          description: "Conflict. The desired tenant slug is already taken (code CONSUMER_SLUG_TAKEN, also returned when a concurrent registration wins the same slug), reserved for platform use or carrying the reserved prefix partner- (code CONSUMER_SLUG_RESERVED), already used by a platform partner (code CONSUMER_SLUG_TAKEN_BY_PARTNER; partners and consumers share one slug namespace), or the partnerOrgId maps to a legacy link that is not yet claimed by any partner consumer (code PARTNER_LINK_UNCLAIMED; run the ownership backfill before retrying). An admitted idempotent registration without its active grant fails with PARTNER_ACCESS_INVARIANT_VIOLATION; an unknown lifecycle value fails closed with PARTNER_REGISTRATION_LIFECYCLE_INVALID. For partner channels that share one symptom-check account, that shared credential must exist on the partner control consumer before pharmacies can be registered: it is missing (code XUND_SHARED_CREDENTIAL_MISSING), not active (code XUND_SHARED_CREDENTIAL_INACTIVE), carries no key material (code XUND_SHARED_CREDENTIAL_UNUSABLE), or several active partner controls claim the channel so the source is ambiguous (code XUND_SHARED_CREDENTIAL_AMBIGUOUS). A platform admin provisions or rotates it before retrying; no tenant is left behind on any of these codes."
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Register a partner pharmacy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{consumerId}/claim:
    post:
      description: Assigns the caller's partnerOrgId to a console-created pharmacy that has an active visibility grant for the caller's explicitly linked platform partner. The operation creates the PartnerLink atomically and is idempotent for the same assignment. Missing, revoked and foreign grants uniformly answer 404. Requires scope partners:register.
      operationId: claimPartnerPharmacy
      parameters:
        - description: Consumer tenant identifier.
          example: 54eab075-ceac-40e1-9ea7-f83a4cf89d06
          in: path
          name: consumerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClaimPartnerPharmacyDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyClaimDto"
          description: The claimed pharmacy registration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The consumer is unknown, inactive, already owned elsewhere, or has no active visibility grant for the caller's explicitly linked platform partner. These cases are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Claim a console-created pharmacy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}:
    get:
      description: Returns the registration state for a partner-registered pharmacy, resolved by the partner-controlled partnerOrgId, including the latest offboarding request state when present. Only registrations owned by the calling partner consumer resolve; unknown, foreign and unclaimed partnerOrgIds uniformly answer 404. Never contains API key material.
      operationId: getPartnerPharmacy
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRegistrationDto"
          description: Registration state for the pharmacy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get a partner pharmacy registration
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates the legal profile and primary address of a pharmacy registration owned by the authenticated ACTIVE partner control (scope partners:register). The operation uses the same transactional mutation as the partner console. Only legalName, street, postalCode, city, country, phone and email are writable. Unknown, foreign and unclaimed partnerOrgIds uniformly answer 404. The required PHI-free reason is validated but not stored; audit metadata records only reasonProvided and changed field names.
      operationId: updatePartnerPharmacyMasterData
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerPharmacyMasterDataDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyMasterDataDto"
          description: Accepted pharmacy master data and stable imprint path.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unknown, foreign, unclaimed, inactive, draining, closed, or has no active pharmacy organization. These cases are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update pharmacy master data
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/additional-confirmation-recipients:
    get:
      description: Returns up to five normalized additional confirmation email recipients for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). Unknown, foreign, unclaimed or inactive targets uniformly return 404.
      operationId: getPartnerPharmacyAdditionalConfirmationRecipients
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAdditionalConfirmationRecipientsDto"
          description: Scoped additional confirmation recipients.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The encrypted recipient configuration is invalid.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get additional confirmation recipients for a partner pharmacy
      tags:
        - s2s
      x-akflow-publication: partner
    put:
      description: Atomically replaces the normalized, deduplicated list of at most five additional confirmation email recipients for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). An empty list disables additional delivery. Addresses and the required PHI-free reason are excluded from audit metadata.
      operationId: replacePartnerPharmacyAdditionalConfirmationRecipients
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerAdditionalConfirmationRecipientsDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAdditionalConfirmationRecipientsDto"
          description: Updated scoped additional confirmation recipients.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. Recipients or the audit reason are invalid.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The recipient configuration changed while editing or is invalid.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Replace additional confirmation recipients for a partner pharmacy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/kim-address:
    get:
      description: Returns the optional KIM address for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). Unknown, foreign, unclaimed or inactive targets uniformly return 404.
      operationId: getPartnerPharmacyKimAddress
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrganizationKimAddressDto"
          description: Scoped KIM address.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get a partner pharmacy KIM address
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Sets or clears the optional KIM address for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). Omitted kimAddress is unchanged; null removes it. The required PHI-free reason and address values are excluded from audit metadata.
      operationId: updatePartnerPharmacyKimAddress
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerKimAddressDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrganizationKimAddressDto"
          description: Updated scoped KIM address.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The KIM address or audit reason is invalid.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The KIM address changed while editing.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update a partner pharmacy KIM address
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/login-links:
    post:
      description: "Issues a one-time magic-login link for the pharmacy backoffice (scope partners:login-links). Magic link is the ONLY login path for partner pharmacy backoffice users; fetch a fresh link on every user click and redirect the browser to loginUrl - links must never be cached, embedded in emails, or logged. Requires an ACTIVE PartnerControl (403 PARTNER_CONTROL_REQUIRED) and only resolves pharmacies registered by the calling partner consumer (foreign or unknown partnerOrgIds answer 404). The token is valid for 120 seconds, single use, and travels exclusively in the URL fragment. Without userRef the link targets the pharmacy owner; an unknown userRef creates a restricted PHARMACY_STAFF user just in time. Preconditions: the tenant must be ACTIVE (409 TENANT_NOT_PROVISIONED while provisioning runs, TENANT_INACTIVE when deactivated) and not draining (409 TENANT_DRAINING). Dedicated rate limit: 10 links per minute per pharmacy (429 with Retry-After)."
      operationId: createPartnerPharmacyLoginLink
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerLoginLinkDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerLoginLinkDto"
          description: One-time login link; the token in the URL fragment is shown exactly once.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: "Conflict. Stable codes: TENANT_NOT_PROVISIONED (keep polling the registration until status ACTIVE), TENANT_INACTIVE (deactivated tenant), TENANT_DRAINING (offboarding in progress), IDENTITY_REALM_MISSING, OWNER_NOT_FOUND, LOGIN_TARGET_INACTIVE."
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The dedicated login-link limit (10 per minute per pharmacy) was exceeded; retry after the Retry-After header.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create a one-time backoffice login link
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/offboarding-requests:
    post:
      description: "Requests offboarding (termination) of a partner-registered pharmacy (scope partners:offboard). Only registrations owned by the calling partner consumer resolve (404 otherwise). Since 2026-07-29 this request itself executes the deactivation; there is no platform-admin confirmation step and no 24h delivery drain window. In one transaction the tenant stops admitting new bookings (DRAINING) and the request starts as EXECUTING (never PENDING_REVIEW). Future appointments are then cancelled (including cross-consumer partner bookings) and each cancellation is delivered as its own appointment.cancelled event (wire type consultation.canceled); the partner-bound webhook stays active until these deliveries are out, then webhooks are disabled, tenant API keys revoked and the tenant closed. The final state is reported via the partner_offboarding.completed webhook event (wire type offboarding.completed), which is also sent when the cleanup finished with errors: the tenant is closed either way and the error detail stays internal. Repeated requests are idempotent and return 200 with the surviving request. The reason must be PHI-free."
      operationId: requestPartnerPharmacyOffboarding
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerOffboardingRequestDto"
        required: true
      responses:
        "201":
          description: ""
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOffboardingRequestedDto"
          description: Offboarding accepted; deactivation executing.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Request partner pharmacy offboarding
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/resource-mode:
    get:
      description: Reads the pharmacy's resource mode (scope partners:register). TEST means the pharmacy books test resources only (the platform QA pool, e.g. ak-MVZ test doctors); LIVE means real MVZ resources. Newly registered partner pharmacies start in TEST (since 2026-08-02); the switch to LIVE is offered in the partner portal settings via the POST variant. Only registrations owned by the calling partner consumer resolve (404 otherwise).
      operationId: getPartnerPharmacyResourceMode
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Current resource mode of the pharmacy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Read partner pharmacy resource mode
      tags:
        - s2s
      x-akflow-publication: partner
    post:
      description: "Switches the pharmacy between TEST (test resources from the platform QA pool) and LIVE (real MVZ resources) with scope partners:register. The switch takes effect immediately for slot search and new bookings; existing bookings are untouched. Idempotent: requesting the current mode returns 200 with changed=false. Every actual switch is audited with the caller's api key as actor; the optional reason must be PHI-free. Only registrations owned by the calling partner consumer resolve (404 otherwise)."
      operationId: updatePartnerPharmacyResourceMode
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerResourceModeDto"
        required: true
      responses:
        "200":
          description: Resource mode after the request.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Switch partner pharmacy resource mode
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/smed-config:
    get:
      description: Returns the optional non-secret SMED identifier for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). Unknown, foreign, unclaimed or inactive targets uniformly return 404.
      operationId: getPartnerPharmacySmedConfig
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerSmedConfigDto"
          description: Scoped SMED configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get a partner pharmacy SMED identifier
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates or clears the optional non-secret SMED identifier for a pharmacy owned by the authenticated ACTIVE partner control (scope partners:register). Omitted smedId is unchanged; null or blank clears it. The required PHI-free reason and identifier are excluded from audit metadata. No token, credential or URL is accepted.
      operationId: updatePartnerPharmacySmedConfig
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerSmedConfigDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerSmedConfigDto"
          description: Updated scoped SMED configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The SMED identifier or audit reason is invalid.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The pharmacy is unavailable in the authenticated partner scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The SMED configuration changed while editing.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update a partner pharmacy SMED identifier
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/webhooks:
    get:
      description: Lists the webhook subscriptions of a partner-registered pharmacy (scope webhooks:write). All webhook endpoints require an ACTIVE PartnerControl (403 PARTNER_CONTROL_REQUIRED) and only resolve pharmacies registered by the calling partner consumer (foreign or unclaimed partnerOrgIds answer 404). Responses never contain secret material.
      operationId: listPartnerPharmacyWebhooks
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerWebhooksResponseDto"
          description: Configured webhooks for the pharmacy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner pharmacy webhooks
      tags:
        - s2s
      x-akflow-publication: partner
    post:
      description: "Creates a webhook subscription for appointment.*, assessment.completed, partner_onboarding.* and partner_offboarding.* events of a partner-registered pharmacy (see the events enum for the exact, authoritative set). Default delivery is HMAC: the signing secret is generated server-side, stored encrypted and returned exactly once in this response; deliveries are signed with HMAC-SHA256 over `${x-akflow-timestamp}.${body}` in the x-akflow-signature header. Alternatively pass `auth` (OAuth2 client credentials: tokenUrl, clientId, clientSecret, and an optional scope sent as the token request's scope parameter when the partner channel requires one) for receivers that expect bearer-authenticated deliveries, such as a partner Apothekenportal; deliveries then carry a Bearer token plus an Idempotency-Key header and no HMAC headers. Client secrets are stored encrypted and never returned. Webhook mutations answer 409 TENANT_DRAINING while an offboarding saga drains the tenant."
      operationId: createPartnerPharmacyWebhook
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerWebhookDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerWebhookDto"
          description: Webhook created; includes the one-time signing secret.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create partner pharmacy webhook
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/webhooks/{webhookId}:
    delete:
      description: Deactivates a webhook subscription. Deliveries stop immediately.
      operationId: deactivatePartnerPharmacyWebhook
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Webhook identifier.
          in: path
          name: webhookId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerWebhookDto"
          description: Deactivated webhook.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Deactivate partner pharmacy webhook
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/pharmacies/{partnerOrgId}/webhooks/{webhookId}/test:
    post:
      description: Enqueues a signed webhook.test delivery to the receiver through the regular dispatcher (including retries). Use it to verify signature validation end to end during onboarding.
      operationId: testPartnerPharmacyWebhook
      parameters:
        - description: Partner-controlled pharmacy identifier from the registration call.
          example: pharmacy-4711
          in: path
          name: partnerOrgId
          required: true
          schema:
            maxLength: 64
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,64}$
            type: string
        - description: Webhook identifier.
          in: path
          name: webhookId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerWebhookTestEnqueuedDto"
          description: Test delivery enqueued.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Send webhook test delivery
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/settings-copy/apply:
    post:
      description: Atomically applies COPY fields and, only with OVERWRITE_CONFLICTS, CONFLICT fields from a matching fresh Preview. Requires partners:register. Idempotency-Key is required; after an ambiguous outcome retry only the identical canonical request with the same header. A 409 caused by drift requires a new Preview. The reason and all copied values remain absent from responses and audit projections.
      operationId: applyPartnerSettingsCopy
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Required opaque retry key. Reuse the identical key only for an explicit retry of the identical canonical Apply request.
          example: settings-copy-01
          in: header
          name: Idempotency-Key
          required: true
          schema:
            maxLength: 128
            minLength: 1
            pattern: ^[A-Za-z0-9._:-]{1,128}$
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ApplyPartnerSettingsCopyDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettingsCopyApplyResultDto"
          description: Value-free settings-copy receipt summary.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "400":
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ApiError"
                  - $ref: "#/components/schemas/ApiValidationError"
                  - $ref: "#/components/schemas/SettingsCopyErrorDto"
          description: Bad Request. Invalid closed body, selectors, duplicate target, pair limit, strategy, revision, reason or Idempotency-Key. Errors never echo submitted values.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Authentication is missing, invalid, expired or revoked.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The authenticated actor lacks the required scope, capability or role.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, unclaimed or inactive partner, consumer, pharmacy or appointment-type targets are deliberately indistinguishable.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettingsCopyErrorDto"
          description: Conflict. Preview drift, FAIL_ON_CONFLICT, malformed stored state, idempotency-key reuse or exhausted serialization retries; no revision, key, digest, hash, reason or copied value is disclosed.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. Request body exceeds 32,768 UTF-8 bytes (32 KiB).
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "415":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unsupported Media Type. Requires application/json with UTF-8 and identity content encoding.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
      security:
        - consumerApiKey: []
      summary: Apply partner pharmacy settings copy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/settings-copy/preview:
    post:
      description: Returns only field names, statuses and counts for a copy between two active pharmacies owned by the same bound platform partner. Requires partners:register. Preview is read-only and creates no receipt or audit. FAIL_ON_CONFLICT is the default; OVERWRITE_CONFLICTS requires a new strategy-bound Preview before Apply.
      operationId: previewPartnerSettingsCopy
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PreviewPartnerSettingsCopyDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettingsCopyPreviewDto"
          description: Value-free settings-copy preview.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "400":
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ApiError"
                  - $ref: "#/components/schemas/ApiValidationError"
                  - $ref: "#/components/schemas/SettingsCopyErrorDto"
          description: Bad Request. Invalid closed body, selectors, duplicate target, pair limit, strategy, revision, reason or Idempotency-Key. Errors never echo submitted values.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Authentication is missing, invalid, expired or revoked.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The authenticated actor lacks the required scope, capability or role.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, unclaimed or inactive partner, consumer, pharmacy or appointment-type targets are deliberately indistinguishable.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettingsCopyErrorDto"
          description: Conflict. Preview drift, FAIL_ON_CONFLICT, malformed stored state, idempotency-key reuse or exhausted serialization retries; no revision, key, digest, hash, reason or copied value is disclosed.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. Request body exceeds 32,768 UTF-8 bytes (32 KiB).
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
        "415":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unsupported Media Type. Requires application/json with UTF-8 and identity content encoding.
          headers:
            Cache-Control:
              description: Settings-copy responses and errors must not be stored by shared or private caches.
              schema:
                example: private, no-store, max-age=0
                type: string
      security:
        - consumerApiKey: []
      summary: Preview partner pharmacy settings copy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/partners/webhooks:
    post:
      description: "Sets the ONE delivery target that serves every pharmacy of the calling partner channel (scope webhooks:write). This is the shape the aTM contract describes: one receiver, routing by data.pharmacy_id, no per-pharmacy registration. Newly registered pharmacies are served immediately, with nothing to configure per pharmacy. A pharmacy-specific webhook still wins where one exists, so single-endpoint pharmacies keep working. Idempotent per channel: a repeated call replaces the existing channel subscription and answers 200, because two active channel targets would double every delivery. url and, for OAuth, the token endpoint are validated against the same SSRF guardrails as the per-pharmacy route."
      operationId: setPartnerChannelWebhook
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerWebhookDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerChannelWebhookDto"
          description: The channel webhook after the request.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Set the channel-wide webhook
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/pharmacy/rooms:
    get:
      description: Lists consultation rooms for a pharmacy organization in the authenticated API key tenant. pharmacyOrgId is optional only when the tenant has a single active pharmacy organization.
      operationId: listPartnerPharmacyRooms
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Optional pharmacy organization identifier. Required when the tenant has more than one active pharmacy organization.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: query
          name: pharmacyOrgId
          required: false
          schema:
            format: uuid
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRoomsResponseDto"
          description: Pharmacy rooms and active room availability rules.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The optional pharmacy organization identifier failed validation.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. No active pharmacy organization exists in the authenticated tenant.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner pharmacy rooms
      tags:
        - s2s
      x-akflow-publication: partner
    post:
      description: Creates a pharmacy consultation room with one initial weekly availability rule. Deactivation is used for lifecycle changes; historical reservations remain intact.
      operationId: createPartnerPharmacyRoom
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerPharmacyRoomDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRoomDto"
          description: Pharmacy room created.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomValidationError"
          description: Bad Request. DTO validation failed or the normalized room name is empty.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The pharmacy organization is absent or outside the authenticated tenant.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomConflictError"
          description: Conflict. A room with the same normalized name already exists.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create partner pharmacy room
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/pharmacy/rooms/{roomId}:
    delete:
      description: Deactivates a pharmacy room and its active availability rules. Historical reservations are retained.
      operationId: deactivatePartnerPharmacyRoom
      parameters:
        - description: Pharmacy consultation room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          in: path
          name: roomId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRoomDto"
          description: Pharmacy room deactivated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The optional pharmacy organization identifier failed validation.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The room is absent or outside the authenticated tenant and pharmacy scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Deactivate partner pharmacy room
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates a pharmacy room display name or active flag inside the authenticated API key tenant.
      operationId: updatePartnerPharmacyRoom
      parameters:
        - description: Pharmacy consultation room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          in: path
          name: roomId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerPharmacyRoomDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerPharmacyRoomDto"
          description: Pharmacy room updated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomValidationError"
          description: Bad Request. DTO validation failed or the update contains no supported room change.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The room is absent or outside the authenticated tenant and pharmacy scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomConflictError"
          description: Conflict. A room with the same normalized name already exists.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update partner pharmacy room
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/pharmacy/rooms/{roomId}/availability-rules:
    post:
      description: Adds a weekly availability rule to a pharmacy room. dayOfWeek uses 0=Sunday through 6=Saturday, dates use YYYY-MM-DD, times use HH:mm, and timezone defaults to Europe/Berlin.
      operationId: createPartnerRoomAvailabilityRule
      parameters:
        - description: Pharmacy consultation room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          in: path
          name: roomId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PartnerPharmacyRoomAvailabilityRuleDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomAvailabilityRuleDto"
          description: Room availability rule created.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The room-rule DTO or optional pharmacy organization identifier failed validation.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The room is absent or outside the authenticated tenant and pharmacy scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomConflictError"
          description: Conflict. The addressed pharmacy room is inactive.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create partner pharmacy room availability rule
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/pharmacy/rooms/{roomId}/availability-rules/{ruleId}:
    delete:
      description: Deactivates a pharmacy room availability rule. Historical reservations are retained.
      operationId: deactivatePartnerRoomAvailabilityRule
      parameters:
        - description: Pharmacy consultation room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          in: path
          name: roomId
          required: true
          schema:
            format: uuid
            type: string
        - description: Availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          in: path
          name: ruleId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomAvailabilityRuleDto"
          description: Room availability rule deactivated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The optional pharmacy organization identifier failed validation.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The room or rule is absent or outside the authenticated tenant and pharmacy scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomConflictError"
          description: Conflict. The addressed pharmacy room is inactive.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Deactivate partner pharmacy room availability rule
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Replaces a pharmacy room availability rule window and keeps the rule active.
      operationId: updatePartnerRoomAvailabilityRule
      parameters:
        - description: Pharmacy consultation room identifier.
          example: ac7515a2-0cf6-4f73-b20b-3b96f3c97c9d
          in: path
          name: roomId
          required: true
          schema:
            format: uuid
            type: string
        - description: Availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          in: path
          name: ruleId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PartnerPharmacyRoomAvailabilityRuleDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomAvailabilityRuleDto"
          description: Room availability rule updated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The room-rule DTO or optional pharmacy organization identifier failed validation.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomNotFoundError"
          description: Not Found. The room or rule is absent or outside the authenticated tenant and pharmacy scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerRoomConflictError"
          description: Conflict. The addressed pharmacy room is inactive.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update partner pharmacy room availability rule
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/providers:
    post:
      description: Creates a provider identity scoped to one organization in the authenticated consumer tenant. Provider identities are tenant-local and are not linked across brands or standalone scheduling tenants. authIssuer and externalId may be omitted together to create an unlinked pending provider. Optional specialtySlugs and availabilityRules allow initial scheduling bootstrap in the same request; availabilityRules additionally require scheduling:write on the API key.
      operationId: createProvider
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateProviderDto"
        required: true
      responses:
        "201":
          description: Provider created and linked to the submitted organization.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create a provider
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/providers/{providerId}/availability-rules:
    post:
      description: Creates a recurring provider availability rule and generates appointment slots for the submitted date range. Dates use YYYY-MM-DD, times use HH:mm, and timezone defaults to Europe/Berlin when omitted.
      operationId: createS2sProviderAvailabilityRule
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateAvailabilityRuleDto"
        required: true
      responses:
        "201":
          description: Availability rule created and slots generated for the requested range.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create provider availability rule
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/providers/{providerId}/slots:
    get:
      description: Lists provider calendar slots for the authenticated API key tenant. When status is omitted, only AVAILABLE slots are returned and slots with active holds are excluded so partner calendars do not offer temporarily reserved times.
      operationId: listS2sProviderSlots
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Start date in YYYY-MM-DD format.
          example: 2026-05-13
          in: query
          name: from
          required: true
          schema:
            format: date
            type: string
        - description: End date in YYYY-MM-DD format.
          example: 2026-05-20
          in: query
          name: to
          required: true
          schema:
            format: date
            type: string
        - description: Specialty slug, for example adipositas.
          example: adipositas
          in: query
          name: specialtySlug
          required: false
          schema:
            type: string
        - description: Optional slot status filter. Defaults to AVAILABLE; AVAILABLE results exclude active slot holds.
          example: AVAILABLE
          in: query
          name: status
          required: false
          schema:
            enum:
              - AVAILABLE
              - BOOKED
              - BLOCKED
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                properties:
                  providerId:
                    description: Provider identifier.
                    example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                    format: uuid
                    type: string
                  range:
                    description: Requested local date range.
                    properties:
                      from:
                        description: Start date.
                        example: 2026-05-13
                        format: date
                        type: string
                      to:
                        description: End date.
                        example: 2026-05-20
                        format: date
                        type: string
                    type: object
                  slots:
                    description: Provider slots sorted by start time.
                    example:
                      - endTime: 2026-05-13T07:30:00.000Z
                        organization:
                          name: MVZ Preview
                          slug: mvz-preview
                        providerId: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                        providerName: Dr. med. Ben Koch
                        slotId: 0d6b61b1-a99e-480c-878f-b8f5d1be0983
                        specialtySlug: adipositas
                        startTime: 2026-05-13T07:00:00.000Z
                        status: AVAILABLE
                        timezone: Europe/Berlin
                    items:
                      description: Provider slot.
                      properties:
                        endTime:
                          description: UTC slot end timestamp.
                          example: 2026-05-13T07:30:00.000Z
                          format: date-time
                          type: string
                        organization:
                          description: Provider organization.
                          properties:
                            name:
                              description: Organization display name.
                              example: MVZ Preview
                              type: string
                            slug:
                              description: Organization slug.
                              example: mvz-preview
                              type: string
                          type: object
                        providerId:
                          description: Provider identifier.
                          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                          format: uuid
                          type: string
                        providerName:
                          description: Provider display name.
                          example: Dr. med. Ben Koch
                          type: string
                        slotId:
                          description: Slot identifier.
                          example: 0d6b61b1-a99e-480c-878f-b8f5d1be0983
                          format: uuid
                          type: string
                        specialtySlug:
                          description: Specialty slug.
                          example: adipositas
                          type: string
                        startTime:
                          description: UTC slot start timestamp.
                          example: 2026-05-13T07:00:00.000Z
                          format: date-time
                          type: string
                        status:
                          description: Slot status.
                          enum:
                            - AVAILABLE
                            - BOOKED
                            - BLOCKED
                          example: AVAILABLE
                          type: string
                        timezone:
                          description: IANA timezone used for local calendar intent.
                          example: Europe/Berlin
                          type: string
                      type: object
                    type: array
                required:
                  - providerId
                  - range
                  - slots
                type: object
          description: Provider slots for the requested local date range.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List provider slots
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/providers/{providerId}/specialties:
    post:
      description: Adds one or more specialty slugs to an existing provider. Send specialtySlug for the legacy single form or specialtySlugs for batch attachment. The specialty must be allowed for the authenticated consumer tenant before public booking can expose matching slots.
      operationId: addProviderSpecialties
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AddSpecialtyDto"
        required: true
      responses:
        "201":
          description: Specialty attached to the provider.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Attach provider specialty
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types:
    get:
      description: Lists tenant-local appointment types and allowed specialties for partner scheduling. Requires scheduling:read. Use organizationId to narrow the result to one organization. Each appointment type includes normalized customIntakeFields with validation rules and an opaque revision for intake-field replacement. Response fields describe which standard and custom intake keys a partner may submit during booking. Invalid stored intake definitions return a generic 409 without field content.
      operationId: listPartnerAppointmentTypes
      parameters:
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Optional organization identifier. When omitted, appointment types for all tenant organizations are returned.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: query
          name: organizationId
          required: false
          schema:
            format: uuid
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypesResponseDto"
          description: Appointment types and allowed specialties for the authenticated consumer tenant.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner appointment types
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types/{appointmentTypeId}/email-message-settings:
    get:
      description: Returns configured, organization/system-inherited and effective confirmation/reminder text and logo visibility with per-field sources for one active appointment type in the authenticated API-key tenant. Requires scheduling:read. The owning pharmacy organization is derived server-side.
      operationId: getPartnerAppointmentTypeEmailMessageSettings
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeEmailMessageSettingsDto"
          description: Appointment-type email message settings.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored email message settings are invalid.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get appointment-type email message settings
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected appointment-type confirmation/reminder text or logo visibility through the shared operation. Requires scheduling:write, the expected opaque revision and a required PHI-free reason. Omitted fields remain unchanged; null restores organization and then system inheritance. Reason and raw configured text never enter logs or audit metadata.
      operationId: updatePartnerAppointmentTypeEmailMessageSettings
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PatchPartnerEmailMessageSettingsDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeEmailMessageSettingsDto"
          description: Updated appointment-type email message settings.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or email message settings are invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The email message settings changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the 16,384-byte mutation limit.
        "415":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unsupported Media Type. Send uncompressed application/json with no charset or charset=utf-8.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update appointment-type email message settings
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types/{appointmentTypeId}/email-reminder:
    get:
      description: Returns configured, resolved organization-inherited and effective email reminder values for one active appointment type in the authenticated API-key tenant. Requires scheduling:read. The owning pharmacy organization is derived server-side.
      operationId: getPartnerAppointmentTypeEmailReminder
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeEmailReminderDto"
          description: Appointment-type email reminder configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored email reminder configuration is invalid.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get appointment-type email reminder configuration
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected appointment-type email reminder values through the shared operation. Requires scheduling:write, the expected revision and a required PHI-free reason. Null restores organization inheritance. The change does not backfill, move or revive existing reminder generations.
      operationId: updatePartnerAppointmentTypeEmailReminder
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerAppointmentTypeEmailReminderDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeEmailReminderDto"
          description: Updated appointment-type email reminder configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or email reminder configuration is invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The email reminder configuration changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the API's 100 KiB body limit.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update appointment-type email reminder configuration
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types/{appointmentTypeId}/intake-fields:
    patch:
      description: Replaces custom intake fields of an active pharmacy appointment type in the authenticated Consumer API-key tenant. Requires scheduling:write. API-key identity, scope, expiry, binding and consumer lifecycle are revalidated inside the mutation transaction. Full replacement of intakeConfig.fields only; all root siblings and other appointment-type settings are preserved. Send the current opaque revision from a read and at most 30 fields. The UTF-8 JSON body is limited to 65,536 bytes (64 KiB); normalized canonical fields JSON is limited to 61,440 bytes. Only application/json with UTF-8 and identity content encoding is accepted. Strings are NFC-normalized and trimmed; duplicate keys/options and unsupported rules are rejected. An unchanged normalized array is a no-op with no write or audit. The required 5–500-code-point trimmed reason is never persisted, returned or logged; audit records only reasonProvided and safe change metadata, never keys, labels, options, help text, rule values or answers. Do not automatically retry PATCH, including after 429, 500 or an ambiguous network failure; reread and reconcile before an explicit new submission. No Idempotency-Key retry contract exists.
      operationId: replacePartnerAppointmentTypeIntakeFields
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReplacePartnerIntakeFieldsDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerIntakeFieldsResponseDto"
          description: Normalized custom intake fields and their current revision.
        "400":
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ApiError"
                  - $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. Invalid path, body, revision, reason or fields, including oversized normalized fields. Errors never reflect field values.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key lacks scheduling:write at the authorization guard.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched targets are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stale revision, concurrent write or invalid stored fields; no field content is disclosed.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. Request body exceeds 65,536 UTF-8 bytes (64 KiB).
        "415":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unsupported Media Type. Requires application/json with UTF-8 and identity content encoding.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. Do not automatically retry PATCH; reread and reconcile before a new submission.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; the result may be ambiguous. Reread and reconcile before a new submission.
      security:
        - consumerApiKey: []
      summary: Replace appointment-type intake fields
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types/{appointmentTypeId}/scheduling-policy:
    get:
      description: Returns configured, organization-inherited and effective values for one active appointment type in the authenticated API-key tenant. Requires scheduling:read. Each null value inherits the corresponding organization value and then the system default; zero remains explicit. Policy changes do not rewrite existing booking records or change bufferMinutes.
      operationId: getPartnerAppointmentTypeSchedulingPolicy
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeSchedulingPolicyDto"
          description: Appointment-type scheduling policy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The appointment-type identifier is not a UUID.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The active appointment type is unavailable in the authenticated consumer scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get an appointment-type scheduling policy
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: "Updates selected scheduling policy fields for one active appointment type in the authenticated API-key tenant. Requires scheduling:write. Omitted fields remain unchanged, null restores per-field organization and system inheritance, and zero is explicit. The required reason is never stored; audit metadata records only reasonProvided: true and safe field changes. Changes apply to subsequent availability, booking, reschedule and self-service cancellation decisions without rewriting existing booking records; bufferMinutes remains unchanged and ineffective."
      operationId: updatePartnerAppointmentTypeSchedulingPolicy
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerSchedulingPolicyWithReasonDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeSchedulingPolicyDto"
          description: Updated appointment-type scheduling policy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The appointment-type identifier or scheduling policy field is invalid.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The active appointment type is unavailable in the authenticated consumer scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update an appointment-type scheduling policy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/appointment-types/{appointmentTypeId}/sms-confirmation:
    get:
      description: Returns configured, organization-inherited and effective SMS confirmation values with their inheritance sources for one active appointment type in the authenticated API-key tenant. Requires scheduling:read. The owning active pharmacy organization is derived server-side from the tenant-scoped appointment type.
      operationId: getPartnerAppointmentTypeSmsConfirmation
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeSmsConfirmationDto"
          description: Appointment-type SMS confirmation configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored SMS confirmation configuration is invalid; no configured text is disclosed.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get appointment-type SMS confirmation configuration
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected appointment-type SMS confirmation values through the shared SMS operation. Requires scheduling:write, the expected revision and a required PHI-free reason. API-key identity, live scope, expiry and exact consumer/type/organization binding are revalidated transactionally. Null restores organization inheritance; reason and raw SMS text never enter logs or audit metadata.
      operationId: updatePartnerAppointmentTypeSmsConfirmation
      parameters:
        - description: appointmentTypeId path parameter.
          example: 0d316943-1a82-4c6f-8b6d-72f0fc823c8b
          in: path
          name: appointmentTypeId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerAppointmentTypeSmsConfirmationDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAppointmentTypeSmsConfirmationDto"
          description: Updated appointment-type SMS configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or SMS configuration is invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The SMS confirmation configuration changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the API's 100 KiB body limit.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update appointment-type SMS confirmation configuration
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/organizations/{organizationId}/email-message-settings:
    get:
      description: Returns configured, system-inherited and effective confirmation/reminder text and logo visibility with per-field sources for one active pharmacy organization in the authenticated API-key tenant. Requires scheduling:read.
      operationId: getPartnerOrganizationEmailMessageSettings
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationEmailMessageSettingsDto"
          description: Organization email message settings.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored email message settings are invalid.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get organization email message settings
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected organization confirmation/reminder text or logo visibility through the shared operation. Requires scheduling:write, the expected opaque revision and a required PHI-free reason. Omitted fields remain unchanged; null restores system inheritance. Reason and raw configured text never enter logs or audit metadata.
      operationId: updatePartnerOrganizationEmailMessageSettings
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PatchPartnerEmailMessageSettingsDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationEmailMessageSettingsDto"
          description: Updated organization email message settings.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or email message settings are invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The email message settings changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the 16,384-byte mutation limit.
        "415":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unsupported Media Type. Send uncompressed application/json with no charset or charset=utf-8.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update organization email message settings
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/organizations/{organizationId}/email-reminder:
    get:
      description: Returns configured, system-inherited and effective email reminder values for one active pharmacy organization in the authenticated API-key tenant. Requires scheduling:read. Consumer authority comes only from the API key.
      operationId: getPartnerOrganizationEmailReminder
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationEmailReminderDto"
          description: Organization email reminder configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored email reminder configuration is invalid.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get organization email reminder configuration
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected organization email reminder values through the shared operation. Requires scheduling:write, the expected revision and a required PHI-free reason. Omitted fields remain unchanged; null restores system inheritance. The change does not backfill, move or revive existing reminder generations.
      operationId: updatePartnerOrganizationEmailReminder
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerOrganizationEmailReminderDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationEmailReminderDto"
          description: Updated organization email reminder configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or email reminder configuration is invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The email reminder configuration changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the API's 100 KiB body limit.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update organization email reminder configuration
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/organizations/{organizationId}/scheduling-policy:
    get:
      description: Returns configured and effective scheduling policy values for one active pharmacy organization in the authenticated API-key tenant. Requires scheduling:read. Null configured values inherit system defaults; zero remains explicit. Policy changes do not rewrite existing booking records or retroactively create or remove buffer blocks. bufferMinutes remains unchanged and has no scheduling-policy effect.
      operationId: getPartnerOrganizationSchedulingPolicy
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationSchedulingPolicyDto"
          description: Organization scheduling policy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The organization identifier is not a UUID.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The active organization is unavailable in the authenticated consumer scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Get an organization scheduling policy
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: "Updates selected scheduling policy fields for one active pharmacy organization in the authenticated API-key tenant. Requires scheduling:write. Omitted fields remain unchanged, null restores inheritance from system defaults, and zero is explicit. The required reason is never stored; audit metadata records only reasonProvided: true and safe field changes. Changes apply to subsequent availability, booking, reschedule and self-service cancellation decisions without rewriting existing booking records; bufferMinutes remains unchanged and ineffective."
      operationId: updatePartnerOrganizationSchedulingPolicy
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerSchedulingPolicyWithReasonDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationSchedulingPolicyDto"
          description: Updated organization scheduling policy.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The organization identifier or scheduling policy field is invalid.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. The active organization is unavailable in the authenticated consumer scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update an organization scheduling policy
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/organizations/{organizationId}/sms-confirmation:
    get:
      description: Returns configured and effective SMS confirmation values with their inheritance sources for one active pharmacy organization in the authenticated API-key tenant. Requires scheduling:read. Consumer authority comes only from the API key; no partner or consumer authority field is accepted from the request body or query.
      operationId: getPartnerOrganizationSmsConfirmation
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationSmsConfirmationDto"
          description: Organization SMS confirmation configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. A path identifier is malformed.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. Stored SMS confirmation configuration is invalid; no configured text is disclosed.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. The configuration could not be read.
      security:
        - consumerApiKey: []
      summary: Get organization SMS confirmation configuration
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates selected organization SMS confirmation values through the shared SMS operation. Requires scheduling:write, the expected revision from the latest read and a required PHI-free reason. API-key identity, live scope, expiry and tenant binding are revalidated in the tenant transaction. Omitted values remain unchanged; reason and raw SMS text never enter logs or audit metadata.
      operationId: updatePartnerOrganizationSmsConfirmation
      parameters:
        - description: organizationId path parameter.
          example: 37d0b63d-886d-4a71-875f-2cab61ca8e5e
          in: path
          name: organizationId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerOrganizationSmsConfirmationDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerOrganizationSmsConfirmationDto"
          description: Updated organization SMS configuration.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiValidationError"
          description: Bad Request. The path, revision, reason or SMS configuration is invalid. Unknown properties are rejected.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. Missing, invalid, revoked, expired or rebound API key, including a scope removed during transactional revalidation.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "404":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Not Found. Foreign, unknown, inactive or mismatched consumers, organizations and appointment types are deliberately indistinguishable.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The SMS confirmation configuration changed while editing or stored configuration is invalid. Reread and reconcile before retrying.
        "413":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Payload Too Large. The JSON request exceeds the API's 100 KiB body limit.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Do not automatically retry PATCH; reread and reconcile because the result may be ambiguous.
      security:
        - consumerApiKey: []
      summary: Update organization SMS confirmation configuration
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/providers/{providerId}/availability-rules:
    get:
      description: Lists provider availability rules for the authenticated API key tenant. The providerId path parameter must belong to the tenant bound to the API key.
      operationId: listPartnerProviderAvailabilityRules
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAvailabilityRulesResponseDto"
          description: Provider availability rules.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner provider availability rules
      tags:
        - s2s
      x-akflow-publication: partner
    post:
      description: "Creates one or more recurring provider availability rules and generates appointment slots for the submitted date range. Send a single rule payload for the legacy form or { rules: [...] } for batch creation. dayOfWeek uses 0=Sunday through 6=Saturday, dates use YYYY-MM-DD, times use HH:mm, and timezone defaults to Europe/Berlin."
      operationId: createPartnerProviderAvailabilityRules
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePartnerAvailabilityRuleDto"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/PartnerAvailabilityRuleResponseDto"
                  - $ref: "#/components/schemas/PartnerAvailabilityRulesResponseDto"
          description: Availability rule created and slots generated for the requested range.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Create partner provider availability rule
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/providers/{providerId}/availability-rules/{ruleId}:
    delete:
      description: Deactivates a provider availability rule and removes unbooked generated slots. Historical bookings are never deleted. If booked slots exist, the API returns 409 and emits PHI-free rebooking evidence.
      operationId: deactivatePartnerProviderAvailabilityRule
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          in: path
          name: ruleId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAvailabilityRuleResponseDto"
          description: Availability rule deactivated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Deactivate partner provider availability rule
      tags:
        - s2s
      x-akflow-publication: partner
    patch:
      description: Updates a provider availability rule in the authenticated API key tenant. If generateFrom and generateTo are supplied, both are required and unbooked generated slots for the rule are regenerated. If booked slots exist, the API returns 409 and emits PHI-free rebooking evidence.
      operationId: updatePartnerProviderAvailabilityRule
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Availability rule identifier.
          example: 7d8f9f4e-0d2f-4f10-8e80-6fd2a884fd21
          in: path
          name: ruleId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePartnerAvailabilityRuleDto"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartnerAvailabilityRuleResponseDto"
          description: Availability rule updated.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: Update partner provider availability rule
      tags:
        - s2s
      x-akflow-publication: partner
  /api/v1/s2s/scheduling/providers/{providerId}/slots:
    get:
      description: Lists provider calendar slots for the authenticated API key tenant through the partner scheduling surface. from and to are required local dates in YYYY-MM-DD format. When status is omitted, only AVAILABLE slots are returned and active temporary holds are excluded.
      operationId: listPartnerSchedulingProviderSlots
      parameters:
        - description: Provider identifier.
          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
          in: path
          name: providerId
          required: true
          schema:
            format: uuid
            type: string
        - description: Optional opaque request correlation ID for tracing API calls across systems. Billing audit paths persist only UUIDv4-shaped values and drop free-form values.
          example: 33333333-3333-4333-8333-333333333333
          in: header
          name: X-Correlation-ID
          required: false
          schema:
            type: string
        - description: Start date in YYYY-MM-DD format.
          example: 2026-05-13
          in: query
          name: from
          required: true
          schema:
            format: date
            type: string
        - description: End date in YYYY-MM-DD format.
          example: 2026-05-20
          in: query
          name: to
          required: true
          schema:
            format: date
            type: string
        - description: Specialty slug, for example adipositas.
          example: adipositas
          in: query
          name: specialtySlug
          required: false
          schema:
            type: string
        - description: Optional slot status filter. Defaults to AVAILABLE; AVAILABLE results exclude active slot holds.
          example: AVAILABLE
          in: query
          name: status
          required: false
          schema:
            enum:
              - AVAILABLE
              - BOOKED
              - BLOCKED
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                properties:
                  providerId:
                    description: Provider identifier.
                    example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                    format: uuid
                    type: string
                  range:
                    description: Requested local date range.
                    properties:
                      from:
                        description: Start date.
                        example: 2026-05-13
                        format: date
                        type: string
                      to:
                        description: End date.
                        example: 2026-05-20
                        format: date
                        type: string
                    type: object
                  slots:
                    description: Provider slots sorted by start time.
                    example:
                      - endTime: 2026-05-13T07:30:00.000Z
                        organization:
                          name: MVZ Preview
                          slug: mvz-preview
                        providerId: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                        providerName: Dr. med. Ben Koch
                        slotId: 0d6b61b1-a99e-480c-878f-b8f5d1be0983
                        specialtySlug: adipositas
                        startTime: 2026-05-13T07:00:00.000Z
                        status: AVAILABLE
                        timezone: Europe/Berlin
                    items:
                      description: Provider slot.
                      properties:
                        endTime:
                          description: UTC slot end timestamp.
                          example: 2026-05-13T07:30:00.000Z
                          format: date-time
                          type: string
                        organization:
                          description: Provider organization.
                          properties:
                            name:
                              description: Organization display name.
                              example: MVZ Preview
                              type: string
                            slug:
                              description: Organization slug.
                              example: mvz-preview
                              type: string
                          type: object
                        providerId:
                          description: Provider identifier.
                          example: 5cd4f03b-5c1d-406e-b834-35b4f635c1c3
                          format: uuid
                          type: string
                        providerName:
                          description: Provider display name.
                          example: Dr. med. Ben Koch
                          type: string
                        slotId:
                          description: Slot identifier.
                          example: 0d6b61b1-a99e-480c-878f-b8f5d1be0983
                          format: uuid
                          type: string
                        specialtySlug:
                          description: Specialty slug.
                          example: adipositas
                          type: string
                        startTime:
                          description: UTC slot start timestamp.
                          example: 2026-05-13T07:00:00.000Z
                          format: date-time
                          type: string
                        status:
                          description: Slot status.
                          enum:
                            - AVAILABLE
                            - BOOKED
                            - BLOCKED
                          example: AVAILABLE
                          type: string
                        timezone:
                          description: IANA timezone used for local calendar intent.
                          example: Europe/Berlin
                          type: string
                      type: object
                    type: array
                required:
                  - providerId
                  - range
                  - slots
                type: object
          description: Provider slots for the requested local date range.
        "400":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Bad Request. The request is syntactically valid JSON but contains invalid fields or formats.
        "401":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unauthorized. The X-API-Key header is missing, expired, or invalid.
        "403":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Forbidden. The API key is valid but does not include the required scope.
        "409":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Conflict. The requested write conflicts with existing tenant data or a slot is no longer available.
        "422":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Unprocessable Entity. The request is valid but violates scheduling business rules.
        "429":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Too Many Requests. The integration should back off and retry later.
        "500":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiError"
          description: Internal Server Error. Retry only when the operation is idempotent or an Idempotency-Key was supplied.
      security:
        - consumerApiKey: []
      summary: List partner provider slots
      tags:
        - s2s
      x-akflow-publication: partner
servers: []
tags:
  - description: Server-to-server operations for integration partners.
    name: s2s
