---
title: "Import a historical (already-occurred) visit as a Completed appointment (ITE-260). Skips the schedule-conflict check — batch imports of past history are expected to overlap each other and existing bookings. The backing schedule item is created without a location (exempt from the overlap EXCLUDE constraint, invisible to room-scoped calendar views) and stamped CreatedBySource = \"import\"."
method: POST
path: "/Appointments/import-historical"
tags: ["Appointments"]
---

# Import a historical (already-occurred) visit as a Completed appointment (ITE-260). Skips the schedule-conflict check — batch imports of past history are expected to overlap each other and existing bookings. The backing schedule item is created without a location (exempt from the overlap EXCLUDE constraint, invisible to room-scoped calendar views) and stamped CreatedBySource = "import".

`POST /Appointments/import-historical`

## Request

- Base URL: `https://api.clinicos.vet/backend/business`
- URL: `https://api.clinicos.vet/backend/business/Appointments/import-historical`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/docs/Appointments/import-historical/post.ts> (a function with typed inputs; its response is checked against the schema)

## Request body

- ImportHistoricalAppointmentRequest: Request to import a single historical (already-occurred) visit as a Completed appointment (ITE-260, parent ITE-218 — AI patient record import). Differences from CreateAppointmentRequest: * Status lands as Completed, never Scheduled. * StartTime/EndTime must be in the past; overlapping imports are expected (batch-importing years of history) so the schedule-conflict check is skipped. * No LocationId — the backing schedule item is created location-less, which both exempts it from the schedule_items_no_location_overlap EXCLUDE constraint and keeps it off room-scoped calendar views. Historical records rarely map to a current exam room anyway. * The schedule item is stamped CreatedBySource = "import" for traceability.
  - `clientId` string, required
  - `patientId` string, required: Patient under care. Historical import is patient-scoped only — group visits are not supported (appointments_subject_chk keeps exactly one subject).
  - `reasonForVisit` string, required
  - `notes` string, nullable: Visit notes from record extraction. Lands on Appointment.Notes so it surfaces in the patient's visit history.
  - `clinicalNarrative` string, nullable: Optional SOAP narrative extracted for this visit (already provider-prefixed). When present, the import creates an AI-generated SOAP note linked to the appointment so the narrative shows in the visit-history SOAP tab. Created here — in the same request/context as the appointment — rather than from the Orchestrate confirm flow, whose shared DbContext can carry a failed, still-tracked entity that a later SaveChanges would re-attempt (PAWTHOSX-BACKEND-7M).
  - `startTime` string, date-time, required: Historical visit start (UTC). Must be in the past.
  - `endTime` string, date-time, required: Historical visit end (UTC). Must be after StartTime and in the past.
  - `title` string, nullable: Schedule item title. Defaults to ReasonForVisit when omitted.
  - `appointmentTypeId` string, nullable: Optional appointment type. Group-visit types are rejected.
  - `customAttributes` string, nullable

## Response `201`

Created

- AppointmentResponseDto: Full appointment response with all related data
  - `id` string
  - `scheduleItemId` string
  - `scheduleItem` ScheduleItemDto: Schedule item DTO (embedded in appointments)
    - `id` string
    - `title` string
    - `startTime` string, date-time
    - `endTime` string, date-time
    - `description` string, nullable
    - `type` string
    - `locationId` string, nullable
    - `location` LocationSummaryDto
      - `id` string
      - `name` string
      - `isActive` boolean
      - `isVehicle` boolean
      - `isPersonalVehicle` boolean
      - `kind` 'Room' | 'Cage' | 'Run' | 'Ward': What a `Location` physically is (ITE-710). Exam rooms are where appointments happen and what the flowboard room grid shows; cages, runs and wards are where a hospitalized patient lives for the length of a `HospitalStay`. The admit picker filters on this, and the flowboard keeps hospitalization locations out of its grid. Stored as text; the default keeps every pre-existing location an exam room.
    - `assignedToId` string, nullable
    - `assignedTo` UserSummaryDto
      - `id` string
      - `email` string
      - `firstName` string, nullable
      - `lastName` string, nullable
      - `displayName` string, nullable
      - `type` string
      - `roleId` string, nullable
      - `roleName` string, nullable
    - `customAttributes` string, nullable
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
  - `clientId` string
  - `client` ClientSummaryDto
    - `id` string
    - `firstName` string
    - `lastName` string
    - `email` string, nullable
    - `phoneNumber` string, nullable
  - `patientId` string, nullable: Set on patient-scoped appointments. Null on group visits — see string? AppointmentResponseDto.PatientGroupId.
  - `patient` PatientSummaryDto: Lightweight patient summary for lists and references
    - `id` string: Unique patient identifier
    - `name` string: The patient's name
    - `species` string: The species name. References a species from GET /species endpoint.
    - `speciesId` string, nullable: The species ID for programmatic lookups.
    - `breed` string: The breed name
    - `sex` string: The patient's sex
    - `dateOfBirth` string, date-time, nullable: Date of birth, if known
    - `isEstimatedAge` boolean
    - `fixed` boolean: Whether the patient is spayed/neutered
    - `treatmentAcceptanceRate` union
      - number, double
      - string, double
  - `patientGroupId` string, nullable: Set on group-visit appointment types (litter / herd). Mutually exclusive with string? AppointmentResponseDto.PatientId.
  - `patientGroup` AppointmentPatientGroupSummaryDto: Lightweight group summary for embedding in appointment responses.
    - `id` string
    - `name` string
    - `groupType` string: "Litter" or "Herd".
    - `speciesName` string, nullable
    - `headCount` union
      - integer
      - string, int32
    - `memberCount` union
      - integer
      - string, int32
  - `reasonForVisit` string
  - `notes` string, nullable
  - `status` string
  - `customAttributes` string, nullable
  - `recordingId` string, nullable
  - `createdAt` string, date-time
  - `updatedAt` string, date-time
  - `isTravelAppointment` boolean
  - `travelDestinationAddress` string, nullable
  - `travelDestinationPlaceId` string, nullable
  - `travelStartingAddress` string, nullable
  - `travelStartingPlaceId` string, nullable
  - `travelDistanceMeters` union
    - integer
    - string, int32
  - `travelDurationMinutes` union
    - integer
    - string, int32
  - `travelIsRoundTrip` boolean, nullable
  - `travelFeeAmount` union
    - number, double
    - string, double
  - `travelAccessNotes` string, nullable
  - `appointmentTypeId` string, nullable
  - `requiresSurgeryRoom` boolean: Whether this appointment type requires a surgery room.
  - `isEmergencySurgeryConversion` boolean: Whether this appointment was converted from a regular exam to emergency surgery.
  - `appointmentTypeDefaultFlowId` string, nullable: Chronicle workflow id sourced from this appointment's <see cref="!:AppointmentType" />. Null falls back to `appointment-default` at the chronicle. Denormalized at read time so the chronicle doesn't need a second appointment-type lookup.
  - `appointmentTypeExamTemplateId` string, nullable: Exam template id sourced from this appointment's <see cref="!:AppointmentType" /> (PAW-741). Resolution at the chronicle exam step: this value, else the provider's personal default, else the standard 7-system view. Denormalized at read time so the chronicle doesn't need a second appointment-type lookup.
  - `appointmentTypeAutoGenerateSoap` boolean: Auto-start SOAP generation when the treatment plan is converted to an invoice (PAW-675). Denormalized from the appointment type; true when the appointment has no type (the platform default is on).
  - `appointmentTypeAutoGenerateDischarge` boolean: Auto-start discharge generation when the SOAP note is approved (PAW-675). Denormalized from the appointment type; true when the appointment has no type (the platform default is on).
  - `careTeam` CareTeamMemberDto[], nullable: The appointment's care team (ITE-1059): the lead first (`isLead`), then the supporting members. Null — and absent from the JSON — while the `AppointmentCareTeam` flag is off.
    - `userId` string
    - `name` string
    - `role` string: A `CareTeamRole` name.
    - `isLead` boolean

## Other responses

- `400`: Bad Request

## Changes

- **2026-10-07** `021fabd866ff`: 3 info
  - added the optional property `careTeam` to the response with the `201` status (media type: text/plain)
  - added the optional property `careTeam` to the response with the `201` status (media type: application/json)
  - added the optional property `careTeam` to the response with the `201` status (media type: text/json)
- **2026-09-11** `503cd0546309`: 3 info
  - added the optional property `scheduleItem/location/oneOf[#/components/schemas/LocationSummaryDto]/kind` to the response with the `201` status (media type: text/plain)
  - added the optional property `scheduleItem/location/oneOf[#/components/schemas/LocationSummaryDto]/kind` to the response with the `201` status (media type: application/json)
  - added the optional property `scheduleItem/location/oneOf[#/components/schemas/LocationSummaryDto]/kind` to the response with the `201` status (media type: text/json)
- **2026-08-07** `a905bde4e796`: 3 info
  - added the optional property `appointmentTypeExamTemplateId` to the response with the `201` status (media type: text/plain)
  - added the optional property `appointmentTypeExamTemplateId` to the response with the `201` status (media type: application/json)
  - added the optional property `appointmentTypeExamTemplateId` to the response with the `201` status (media type: text/json)

[Operation history](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/changes/Appointments/import-historical/post.md)

---

[API](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1.md) - [All operations](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/llms.txt) - [OpenAPI document](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/revisions/099cf36186e0?raw)
