Skip to main content

Create night report PDF

MethodPath
POST/v1/slim/export/pdf

Authentication · Access policies

Creates a night report PDF for one resident and stores it. Optionally emails the PDF. Use it for the report download and email feature on the dashboard.

Auth: bearer token. The caller must be a practitioner, an admin or a System Owner, and needs search and read on Patient, Device and Observation. Scope: the caller's project (from the token). The resident is read with your token, so Medplum's access policy limits which residents you can export.

Behaviour​

  • code must be TRENDS_PDF_EXPORT. Any other value is rejected with 400.
  • The report layout comes from the export template content for code and language. A template in your project wins over one in its parent project. The route returns 400 when no template exists.
  • The report period is (period.start, period.end] in the project's time zone: for a range of more than one day the first day is left out, because its night belongs to the day before. A single-day range reports that day. A night counts for the day its sleep ends.
  • The report covers sleep statistics, heart rate and respiratory rate for each night. It holds only what ends inside one of the resident's use periods of its device, as GET /v1/slim/sleep/statistics does: the sleep table's recordings, and the readings behind the heart and respiratory rate rows and charts. A reading with no end time is then left out. So a previous resident's night that ended before the device was handed over, but reached Ovok after it, is not reported. A resident with no device use history has everything reported.
  • When a night has several sleep recordings left, the sleep table uses the one written last (latest meta.lastUpdated), the rule GET /v1/slim/sleep/statistics uses.
  • Once a resident has any use period, the report also leaves out what a device with no period of theirs recorded, and what a device recorded before its earliest period. A device assigned before use periods were recorded gets its first one on its next edit in Ovok, starting at the Device's last write before that edit, so what it recorded before then is not reported. Each device whose readings in a report all drop is counted in the sleep.device_use_device_dropped metric and logged at most once a minute.
  • Report times use the project's time zone. The timeZone field in the body is not used.
  • The PDF is stored as a Binary, and a DocumentReference links it to the resident. Both are written in one transaction, so a failed store leaves neither. The response is that DocumentReference. Its content[0].attachment.url points to the Binary.
  • When mailTo has addresses, the PDF is emailed to them as an attachment after the store succeeds. The email is sent in the language you set. With no addresses, nothing is emailed.
  • If the email cannot be sent, the route returns 500, but the report has already been stored.
  • Every call creates a new report. Nothing is deduplicated.

Example​

curl -X POST 'https://api.sandbox.ovok.com/v1/slim/export/pdf' \
-H "Authorization: Bearer ${OVOK_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"code": "TRENDS_PDF_EXPORT",
"patientId": "3f1c2b7e-8d4a-4c1e-9b2f-6a7d5e4c3b21",
"language": "en",
"period": { "start": "2026-09-21T00:00:00Z", "end": "2026-09-28T00:00:00Z" },
"mailTo": ["team@example.com"]
}'

Successful response​

201 — The stored DocumentReference that links the PDF to the resident.

Errors​

StatusMeaning
400Your session has no project, the resident cannot be read, code is not TRENDS_PDF_EXPORT, no export template exists for code and language (or it has no main content), or the period covers no night.
401Bearer token is missing, invalid or expired.
403You are not a practitioner, admin or System Owner, or you lack search or read on Patient, Device or Observation.
422The body fails validation.
502Medplum answered the read of the observations, devices or the resident's device use periods with an error, or failed to store the PDF.