---
title: "Discharge the patient. Gated on the originating visit's discharge checklist (409 `DISCHARGE_BLOCKED` with the checklist in the body). Standing orders on the stay are discontinued in the same transaction so nothing keeps generating occurrences for a patient who went home. Returns the discharge summary (ITE-710): the entry plus the unperformed billable occurrences and the estimate id — the caller converts the estimate themselves; nothing here writes a bill."
method: POST
path: "/hospitalstays/{id}/discharge"
tags: ["HospitalStays"]
---

# Discharge the patient. Gated on the originating visit's discharge checklist (409 \`DISCHARGE_BLOCKED\` with the checklist in the body). Standing orders on the stay are discontinued in the same transaction so nothing keeps generating occurrences for a patient who went home. Returns the discharge summary (ITE-710): the entry plus the unperformed billable occurrences and the estimate id — the caller converts the estimate themselves; nothing here writes a bill.

`POST /hospitalstays/{id}/discharge`

## Request

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

## Path parameters

- `id` string, required

## Request body

- DischargeHospitalStayRequest: Discharge a stay. `DischargedAt` defaults to the server clock when omitted.
  - `note` string, nullable
  - `dischargedAt` string, date-time, nullable

## Response `200`

OK

- HospitalStayDischargeSummaryDto: Response of `POST /hospitalstays/{id}/discharge` (ITE-710). The discharged board entry (same shape as before, so existing readers keep working) plus what the user needs before converting the estimate themselves: the estimate id, the orders this discharge discontinued, the unperformed billable occurrences and the authorization envelope. The estimate is NEVER converted here and no invoice row is written — the bill is still born by converting the estimate (docs/billing-happy-paths.md).
  - `estimateId` string, nullable: The stay's running estimate, to convert. Null when the stay never charged anything.
  - `discontinuedOrderIds` string[]: Orders that were still active/held and were discontinued by this discharge.
  - `unperformedBillables` UnperformedBillableOccurrenceDto[]
    - `orderId` string
    - `orderTitle` string
    - `orderKind` 'medication' | 'fluid' | 'diagnostic' | 'monitoring' | 'procedure' | 'nursing' | 'nutrition' | 'communication' | 'task': What kind of thing a treatment order is. Mirrors the prototype's `TreatmentOrderKind` so the web mirror can map one-to-one.
    - `occurrenceId` string
    - `dueAt` string, date-time
    - `serviceCatalogItemId` string, nullable
    - `inventoryItemId` string, nullable
    - `billableItemId` string, nullable
  - `authorization` TreatmentAuthorizationDto: The authorization rail: what the client approved, what has been charged, what the schedule says is still coming. Shape mirrors `TreatmentAuthorization` in the web treatment view models. Amounts are 2dp, rounded half away from zero to match the Postgres numeric(10,2) convention the estimate itself is stored in.
    - `approvedMin` union: Low end of the range the client accepted; null until the estimate is accepted.
      - number, double
      - string, double
    - `approvedMax` union: High end of the range the client accepted; null until the estimate is accepted.
      - number, double
      - string, double
    - `deliveredAmount` union: Value of Performed estimate lines captured from this stay's completed occurrences.
      - number, double
      - string, double
    - `projectedAmount` union: decimal TreatmentAuthorizationDto.DeliveredAmount plus unit price × expected remaining occurrences of every active billable order — derived from the schedule, not counted from lines.
      - number, double
      - string, double
    - `unapprovedAmount` union: Value of estimate lines the client has not approved (added after the last acceptance, or never accepted).
      - number, double
      - string, double
    - `currency` string: ISO 4217 code from the clinic's region settings ("USD" / "GBP").
  - `checklist` DischargeChecklistDto: Result of evaluating the "Missing Before Discharge" safety checklist for an appointment (PAW-628). Items are grouped by how they gate discharge so the UI can render three sections: required, recommended, and already-completed.
    - `appointmentId` string
    - `required` DischargeChecklistItemDto[]: Items that must be resolved or overridden before discharge.
      - `key` string
      - `category` string: medical | financial | communication | inventory
      - `status` string: missing | complete | overridden | pending
      - `severity` string: required | warning
      - `title` string
      - `explanation` string
      - `actionLabel` string, nullable: Label for the direct-action button, e.g. "Finalize invoice". Null when no action applies.
      - `actionTarget` string, nullable: Frontend deep-link hint for the action button, e.g. "invoice", "dispense", "schedule". The chronicle UI maps these to the relevant tab/route.
      - `canOverride` boolean: Whether the current user is permitted to override this item.
      - `override` ChecklistOverrideDto: Audit record of an override: reason, user, timestamp.
        - `reason` string
        - `userId` string, nullable
        - `timestamp` string, date-time
    - `recommended` DischargeChecklistItemDto[]: Items worth attention but not blocking (warning-only).
      - `key` string
      - `category` string: medical | financial | communication | inventory
      - `status` string: missing | complete | overridden | pending
      - `severity` string: required | warning
      - `title` string
      - `explanation` string
      - `actionLabel` string, nullable: Label for the direct-action button, e.g. "Finalize invoice". Null when no action applies.
      - `actionTarget` string, nullable: Frontend deep-link hint for the action button, e.g. "invoice", "dispense", "schedule". The chronicle UI maps these to the relevant tab/route.
      - `canOverride` boolean: Whether the current user is permitted to override this item.
      - `override` ChecklistOverrideDto: Audit record of an override: reason, user, timestamp.
        - `reason` string
        - `userId` string, nullable
        - `timestamp` string, date-time
    - `completed` DischargeChecklistItemDto[]: Items that passed — shown for reassurance, not action.
      - `key` string
      - `category` string: medical | financial | communication | inventory
      - `status` string: missing | complete | overridden | pending
      - `severity` string: required | warning
      - `title` string
      - `explanation` string
      - `actionLabel` string, nullable: Label for the direct-action button, e.g. "Finalize invoice". Null when no action applies.
      - `actionTarget` string, nullable: Frontend deep-link hint for the action button, e.g. "invoice", "dispense", "schedule". The chronicle UI maps these to the relevant tab/route.
      - `canOverride` boolean: Whether the current user is permitted to override this item.
      - `override` ChecklistOverrideDto: Audit record of an override: reason, user, timestamp.
        - `reason` string
        - `userId` string, nullable
        - `timestamp` string, date-time
    - `pending` DischargeChecklistItemDto[]: Items whose subject doesn't exist yet (no invoice created, no vaccines administered, no SOAP plan...). Never block completion; rendered as upcoming rather than green so the live rail doesn't claim success before the work has happened (PAW-675).
      - `key` string
      - `category` string: medical | financial | communication | inventory
      - `status` string: missing | complete | overridden | pending
      - `severity` string: required | warning
      - `title` string
      - `explanation` string
      - `actionLabel` string, nullable: Label for the direct-action button, e.g. "Finalize invoice". Null when no action applies.
      - `actionTarget` string, nullable: Frontend deep-link hint for the action button, e.g. "invoice", "dispense", "schedule". The chronicle UI maps these to the relevant tab/route.
      - `canOverride` boolean: Whether the current user is permitted to override this item.
      - `override` ChecklistOverrideDto: Audit record of an override: reason, user, timestamp.
        - `reason` string
        - `userId` string, nullable
        - `timestamp` string, date-time
    - `evaluatedAt` string, date-time
    - `hasBlockingItems` boolean: True when at least one required item is still unresolved (status == "missing"). When true the discharge/completion gate should block until resolved or overridden.
    - `isEuthanasiaVisit` boolean: True when the visit is detected as a euthanasia/end-of-life visit (ITE-323). The discharge tab uses this to default generation off and show the "Generate anyway" affordance instead.
    - `euthanasiaSignal` string, nullable: Human-readable reason for the euthanasia detection, when detected.
  - `stay` HospitalStayDto: The stay header. Billing state is not on this record by design — string? HospitalStayDto.EstimateId points at the stay's running estimate and the estimate is the authority for what has been charged.
    - `id` string
    - `patientId` string
    - `clientId` string
    - `appointmentId` string, nullable
    - `caseId` string, nullable
    - `locationId` string, nullable
    - `locationName` string, nullable
    - `attendingUserId` string, nullable
    - `attendingName` string, nullable
    - `assignedUserIds` string[]: Assigned nurse/tech crew, parallel to List&lt;string&gt; HospitalStayDto.AssignedNames.
    - `assignedNames` string[]
    - `acuity` 'stable' | 'watch' | 'critical': How sick the patient is right now — drives board sort and colour, not clinical logic.
    - `status` 'Active' | 'Discharged' | 'Closed': Lifecycle of a `HospitalStay`. Discharged means the patient has physically left; Closed means the stay's paperwork (billing, discharge doc) is finished and it should drop off the board entirely.
    - `admittedAt` string, date-time
    - `dischargedAt` string, date-time, nullable
    - `closedAt` string, date-time, nullable
    - `estimateId` string, nullable
    - `reasonForStay` string, nullable
    - `note` string, nullable
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
    - `authorization` TreatmentAuthorizationDto: The authorization rail: what the client approved, what has been charged, what the schedule says is still coming. Shape mirrors `TreatmentAuthorization` in the web treatment view models. Amounts are 2dp, rounded half away from zero to match the Postgres numeric(10,2) convention the estimate itself is stored in.
      - `approvedMin` union: Low end of the range the client accepted; null until the estimate is accepted.
        - number, double
        - string, double
      - `approvedMax` union: High end of the range the client accepted; null until the estimate is accepted.
        - number, double
        - string, double
      - `deliveredAmount` union: Value of Performed estimate lines captured from this stay's completed occurrences.
        - number, double
        - string, double
      - `projectedAmount` union: decimal TreatmentAuthorizationDto.DeliveredAmount plus unit price × expected remaining occurrences of every active billable order — derived from the schedule, not counted from lines.
        - number, double
        - string, double
      - `unapprovedAmount` union: Value of estimate lines the client has not approved (added after the last acceptance, or never accepted).
        - number, double
        - string, double
      - `currency` string: ISO 4217 code from the clinic's region settings ("USD" / "GBP").
  - `patient` TreatmentBoardPatientDto: Patient header shown on every board card and on the patient rail.
    - `id` string
    - `name` string
    - `species` string, nullable
    - `breed` string, nullable
    - `sex` string, nullable
    - `ageDisplay` string, nullable: "3y 2m" style, computed from the date of birth on the server clock.
    - `dateOfBirth` string, date-time, nullable
    - `weightKg` union: Current weight for dose calculation, in kilograms rounded to 2 dp. Sourced from the patient's most recent `VitalMeasurement` (by `TakenAt`) whose type is the "weight" vital: the free-text value is parsed and converted from the type's unit (or a unit suffix in the value) by `WeightKilograms`. Null when the patient has no weight vital, or the latest one cannot be read as a weight.
      - number, double
      - string, double
    - `weightTakenAt` string, date-time, nullable: When decimal? TreatmentBoardPatientDto.WeightKg was taken, so the UI can flag a stale weight. Null with it.
    - `photoUrl` string, nullable: Profile photo. Not populated yet — presigning it needs `IFileStorageService`, which the Business API test suite mocks, so it is deliberately left to the web slice.
    - `clientName` string, nullable
  - `orders` TreatmentOrderDto[]
    - `id` string
    - `stayId` string
    - `kind` 'medication' | 'fluid' | 'diagnostic' | 'monitoring' | 'procedure' | 'nursing' | 'nutrition' | 'communication' | 'task': What kind of thing a treatment order is. Mirrors the prototype's `TreatmentOrderKind` so the web mirror can map one-to-one.
    - `title` string
    - `subtitle` string, nullable
    - `state` 'active' | 'held' | 'discontinued' | 'completed': Workflow state of an order. Completed is reached when the schedule runs out (or every occurrence is resolved); Discontinued is a clinician stopping it early. Both are terminal — an order is never hard-deleted, so the audit trail survives.
    - `priority` 'routine' | 'important' | 'critical': Clinical urgency of an order. Distinct from Priority, which is a task concept.
    - `scheduleType` 'once' | 'interval' | 'times' | 'continuous' | 'prn': How an order recurs. The occurrence rows themselves are materialized by the scheduling engine (ITE-701); this enum is only the declaration of intent.
    - `scheduleLabel` string, nullable
    - `intervalMinutes` union
      - integer
      - string, int32
    - `startAt` string, date-time, nullable
    - `endAt` string, date-time, nullable
    - `times` string[]: Explicit due times for `times` schedules, stored exactly as the client sent them.
    - `maxOccurrences` union
      - integer
      - string, int32
    - `medication` TreatmentMedicationDetailsDto: Medication dosing detail. Every field optional — see the entity's landmine note.
      - `drug` string, nullable
      - `dose` union
        - number, double
        - string, double
      - `doseUnit` string, nullable
      - `calculatedDose` union
        - number, double
        - string, double
      - `calculatedDoseUnit` string, nullable
      - `concentration` union
        - number, double
        - string, double
      - `concentrationUnit` string, nullable
      - `calculatedVolumeMl` union
        - number, double
        - string, double
      - `route` string, nullable
      - `maxDose` union
        - number, double
        - string, double
    - `fluid` TreatmentFluidDetailsDto: Fluid-therapy detail. Every field optional — see the entity's landmine note.
      - `fluid` string, nullable
      - `rateMlHr` union
        - number, double
        - string, double
      - `bolusMlKg` union
        - number, double
        - string, double
      - `calculatedBolusMl` union
        - number, double
        - string, double
      - `additives` string[], nullable
    - `instructions` string, nullable
    - `resultUnit` string, nullable
    - `serviceCatalogItemId` string, nullable
    - `inventoryItemId` string, nullable
    - `billableItemId` string, nullable
    - `createdBy` string: Display name of the author; falls back to the user id, never null.
    - `createdById` string, nullable
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
    - `heldAt` string, date-time, nullable
    - `discontinuedAt` string, date-time, nullable
    - `completedAt` string, date-time, nullable
    - `occurrences` TreatmentOccurrenceDto[]
      - `id` string
      - `orderId` string
      - `dueAt` string, date-time
      - `status` 'pending' | 'completed' | 'skipped' | 'held': State of one scheduled slot of an order.
      - `kind` 'clinical' | 'billing': What an occurrence row stands for. The Now view, the care board and the awareness engine only ever look at TreatmentOccurrenceKind.Clinical rows; TreatmentOccurrenceKind.Billing rows are the daily charge cadence for continuous orders (ITE-735) and must never surface as nursing work.
      - `completedAt` string, date-time, nullable
      - `completedById` string, nullable
      - `completedBy` string, nullable
      - `actualValue` string, nullable
      - `note` string, nullable
      - `skippedReason` string, nullable
      - `heldAt` string, date-time, nullable
      - `occurrenceKey` string
      - `estimateLineItemId` string, nullable: The estimate line this completion was charged as (ITE-703); null when nothing was captured.
    - `events` TreatmentOrderEventDto[]: The append-only audit trail, oldest first.
      - `id` string
      - `orderId` string
      - `occurrenceId` string, nullable
      - `action` 'created' | 'edited' | 'completed' | 'skipped' | 'held' | 'resumed' | 'discontinued' | 'delayed' | 'charge_captured' | 'charge_capture_failed': Append-only audit actions on the treatment-order trail, mirroring MedicationRequestEventType for the medication-request trail.
      - `at` string, date-time
      - `actor` string
      - `actorUserId` string, nullable
      - `detail` string, nullable
  - `lastSeenAt` string, date-time, nullable: The caller's "last looked at this sheet" marker (ITE-704), or null when they have never looked. Per user: two people reading the same board get different values.
  - `changedSinceLastSeen` union: Audit events on this stay's orders after DateTime? TreatmentBoardEntryDto.LastSeenAt; 0 when there is no marker.
    - integer
    - string, int32

## Other responses

- `404`: Not Found
- `409`: Conflict

## Changes

- **2026-09-11** `503cd0546309`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/clinicos/apis/pawthosx-business-api-v1/changes/hospitalstays/:id/discharge/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)
