{"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"},"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"}},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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.3.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. 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}/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/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}/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/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/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"}]}
