You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zoo-api/zoo-api.yaml

671 lines
30 KiB
YAML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

openapi: 3.0.3
info:
title: Zorg op Orde API
description: |-
Copyright Zorg op Orde All rights reserved.
Security is done, for now, via cookies - i.e. just make the API request,
if done from a browser session that is logged in, the API request is handled.
All API requests can return an error state of 'not logged in' or 'not authorized'
(which means, some user is logged in, but is not allowed to see / act the thing they want to see / act on).
contact:
name: Zorg op Orde tech lead
email: r.zwitserloot@zorgoporde.nl
version: 0.1-DEV
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
servers:
- url: https://tools.zorgoporde.nl/api1
description: Production
- url: https://test.zorgoporde.nl/api1
description: Testing
tags:
- name: core
description: |-
API for cross-cutting API concerns, such as authentication and the springboard.
- name: patient
description: |-
API for retrieving medical dossier data and concerns based on looking up a
specific patient.
- name: QoC
description: |-
API related to Quality of Care features
A care program (dutch: _ketenzorg_ or _zorgprogramma_) describes a specific disease (such as Diabetes or Astma) or a more abstract concern such as elderly care or general concern about cardiovascular health. The same care program can show up multiple times, as there are different care programs and standards for the same disease or concern. For example, there could be the InEen report 'take' on how one should provide Diabetes care, and there could be some regional group's slightly different take on it; these would show up as different care programs.
Any given customer has a 'fave' status for any given care program; some care programs are enabled by default and some are disabled by default. However, a customer can explicitly select a program they wouldn't ordinarily see ('favourite' it), or explicitly deselect a program they get by default ('unfavourite' it). Most care programs will be neither favourited nor unfavourited: They should be shown based on their `defaultShow` property.
To allow favouriting/unfavouriting, the front end has 2 separate views for selecting care programs: The usual view, which shows _only_:
- Care programs that customer has explicitly favourited.
- Care programs that are shown by default to this customer which they did not explicitly unfavourite.
As well as a 'config' view where they see _all_ care programs that could possibly be relevant for that customer, where the customer can preview the report (essentially, run the report as normal), favourite something they don't get by default, or unfavourite something they get by default.
paths:
/springboard/apps:
get:
tags:
- core
summary: Available springboard apps
description: WorkInProgress
responses:
'200':
description: List of available apps
content:
application/json:
schema:
type: object
properties:
notifications:
type: string
apps:
type: array
items:
type: string
/patient/dossier:
get:
tags:
- patient
summary: Get detailed medical dossier info for the stated patient
parameters:
- name: bsn
in: query
description: |-
The SSN (dutch: _BSN_) of a patient to look up. May only contain digits, cannot contain more than 9 digits, and cannot be 0.
Either `bsn` or `pu` must be present.
schema:
type: string
example: 123456789
- name: pu
in: query
description: |-
The Patient unique ID, as e.g. reported by `/patient/base`'s `pat_unid` response.
Either `bsn` or `pu` must be present.
schema:
type: string
example: ""
- name: q
in: query
description: |-
A space, comma, or bar-separated list of dossier aspects to query. If omitted, everything is returned.
The keys match the keys in the JSON structure that is returned on a success, such as `medication` or `measurements`.
schema:
type: string
example: "medication,measurements"
responses:
'200':
description: Detailed medical dossier information for the patient is returned.
content:
application/json:
schema:
type: object
properties:
tbd:
description: |-
Work in progress
type: string
example: Work in progress
/patient/base:
get:
tags:
- patient
summary: Get basic personal info not directly related to their medical dossier
parameters:
- name: bsn
in: query
description: |-
The SSN (dutch: _BSN_) of a patient to look up. May only contain digits, cannot contain more than 9 digits, and cannot be 0.
required: true
schema:
type: string
example: 123456789
- $ref: '#/components/parameters/Authorization'
responses:
'200':
description: Basic personal information for the patient is returned.
content:
application/json:
schema:
type: object
properties:
bsn:
description: |-
Patient SSN (dutch: _BSN_). Always 9 digits, left-0-padded if necessary.
If unknown or left blank, will be 9 zeroes.
type: string
example: 123456789
name:
description: All relevant info about the patient's name.
type: object
properties:
firstname:
description: |-
Patient's first name(s), separated by spaces.
It's possible that no first names are known and instead only initials are known; in that case,
the initials are provided with dots (`.`) in between the letters, e.g. `"J.M."`.
type: string
example: Marie Antoinnette
initials:
description: |-
Patient's initials, with no separators.
Initials might be derived from a patient's first name if initials weren't explicitly provided by
the source HIS.
type: string
example: MA
infix_own:
description: |-
The prefix of the patient's own last name (what they were born with; not the name inherited from
a spouse): `van`, `de`, `van der` - a mostly uniquely dutch aspect to last names.
type: string
example: de
own_lastname:
description: |-
The patient's own last name without a prefix (what they were born with; not the name inherited from
a spouse).
type: string
example: Villepin
infix_partner:
description: |-
The prefix of the patient's (ex-)spouse's last name; not all patients that are married go by their spouse's last name and often, if they don't, this field will be blank.
type: string
example: van der
partner_lastname:
description: |-
The the patient's (ex-)spouse's last name without prefix; not all patients that are married go by their spouse's last name and often, if they don't, this field will be blank.
type: string
example: Dussen
gender:
description: |-
Patient's gender. `M` = male, `V` = female, `O` = other/unknown.
Follows [NHG-table-4](https://referentiemodel.nhg.org/sites/default/files/NHG-Tabel%204-Geslacht-versie-5-Inkijkexemplaar_1.pdf).
type: string
example: V
enum:
- M
- V
- O
dob:
description: |-
Patient's date of birth.
Note that by convention, patients whose birthdate is unknown pick a date and tend to pick either `xxxx-01-01` or `xxxx-07-01`. Can, in rare cases, be blank - if birth date is not known.
type: string
format: date
example: 1970-07-01
address:
description: Patient's address (where they live).
type: object
properties:
street:
description: Full name of the street; can be blank if not known or not provided, and excludes house number.
type: string
example: Lange Geer
hn:
description: |-
Just the house number; 0 if unknown or in the exotic case where no house number exists. This does
not include any addendums such as 'A' or 'room 15'. Guaranteed to be non-negative.
type: integer
example: 4
hn_suffix:
description: |-
Often empty, the string that follows the numeric part of the address house number. For example, `"A"`, or
`"k22"`.
type: string
example: A
postcode:
description: The post code, in `1234AB` format. If not known, blank.
type: string
example: 2611PV
city:
description: The city or town.
type: string
example: Delft
contact:
type: object
properties:
tel:
description: |-
Patient's phone number(s). By convention, the mobile number, if available, is always listed first.
Phone numbers are always in international format (they start with a `+` symbol).
If no phone numbers are available or patient has no phone, an empty list is returned.
type: array
example: ["+31612345678", "+31701234567"]
items:
type: string
email:
description: |-
Patient's email address(es); first one returned is indicated as preferred.
If no emails are known or available, or patient has no email, an empty list is returned.
type: array
items:
type: string
example: ["info@zorgoporde.nl"]
insurance:
type: object
properties:
policy_number:
description: |-
Patient's insurance registration number (dutch: _polisnummer_). If not known or not insured, a blank string.
type: string
example: 123456789012345
uzovi:
description: |-
Insurer's identity number in the dutch insurance system (dutch: _UZOVI nummer_). Always
4 digits exactly, 0-left-padded if needed. If unknown or not insured, 4 zeroes.
type: string
example: 3331
patid:
description: |-
Patient's "public" ID, as used and shown on the HIS patient page. Not necessarily unique,
and not necessarily present; 0 indicates no patid is known or this HIS does not use (numeric)
public IDs.
type: number
example: 1234
pat_unid:
description: |-
Patient's unique and persistent ID in HIS. Usually identical to `patid` but certain HISes may
use UUID, or has globally unique keys (e.g. very large numbers). Can be blank, but only
if supplying HIS does not send them.
type: string
example: 1234
start_date:
type: string
format: date
description: |-
Date patient joined the practice (dutch: _inschrijf datum_). If blank, patient joined a
long time ago. By convention if programming a system that requires a value, a sentinel
value of `"1900-01-01"` is suggested for this case. (when reading from this API, map
the empty string onto that date if you prefer not having blank/NULL values).
example: 1994-08-20
end_date:
type: string
format: date
description: |-
If not blank, patient has exited the practice on this date. (dutch: _uitschrijf datum_).
example: ""
end_reason:
description: |-
Reason patient left the practice (dutch: _reden vertrek_).
This will always be blank if `end_date` is blank. Otherwise, this value _might_ contain
a non-blank letter as per [NHG-table-9](https://referentiemodel.nhg.org/sites/default/files/NHG-Tabel%209-Reden%20vertrek-versie-5-Inkijkexemplaar_1.pdf):
- `A` = To other practice
- `V` = Moved
- `O` = died
- `T` = Temporary
- `I` = Care home / institution
- `Q` = unknown
- `X` = Other
type: string
example: ""
doctor:
description: |-
If known, the AGB code of the primary care GP (dutch: _Inschrijf arts_). Value 0 indicates
this HIS or practice doesn't assign patients to individual GPs, or this information isn't
known.
type: number
example: 1051234
category:
description: |-
The status of the patient's registration within this practice.
As per [NHG-table-5](https://referentiemodel.nhg.org/sites/default/files/NHG-Tabel%205-Categorie%20pati%C3%ABnt-versie-5-Inkijkexemplaar_1.pdf):
- `V` = Standard patient, part of the GP's population (dutch: _vast_).
- `T` = Temporary patient (likely do _not_ treat as part of GP's population).
- `P` = Opportunity patient (dutch: _passant_ - patient is not signed up with this GP. For example: tourist).
type: string
example: V
'400':
description: The request is invalid; for example, it doesn't contain the required `BSN` parameter.
'401':
$ref: '#/components/responses/JwtFailure'
'403':
description: Indicated practice is known but has not authorized ZOO to share this information with signer.
'404':
$ref: '#/components/responses/PatNotFound'
/qoc/careprogram:
get:
tags:
- QoC
summary: List all available care programs
description: Includes all care programs that the user is allowed to see, even ones that are unfavourited or not shown by default.
responses:
'200':
description: Care programs are returned
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/CareProgram'
'401':
$ref: '#/components/responses/NoAuth'
'403':
$ref: '#/components/responses/NoAccess'
/qoc/careprogram/{careprogramKey}/fave:
put:
tags:
- QoC
summary: Favourite, unfavourite, or clear fav status for a given CareProgram
parameters:
- name: careprogramKey
in: path
description: key of care program for which the fav status needs to be changed
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: string
example: T
enum:
- T
- F
- X
responses:
'200':
description: Fav status is updated
content:
application/json:
schema:
type: object
properties:
key:
description: The care program key as provided
type: string
example: ZEL-dm2
value:
description: The current fav status of this careprogram
type: string
example: T
enum:
- T
- F
- X
defaultShow:
description: Whether this care program should be default-shown or not.
type: boolean
'401':
$ref: '#/components/responses/NoAuth'
'403':
$ref: '#/components/responses/NoAccess'
/qoc/indicatorset/{setKey}:
get:
tags:
- QoC
summary: Load an indicator-based report
parameters:
- name: setKey
in: path
description: The key as listed in the `CareProgram` schema.
required: true
schema:
type: string
example: ZEL-dm2
- name: refDate
in: query
description: |-
The date in `2023-04-01` format; defaults to the first day in the next quarter, e.g. on april 5th 2023, defaults to `2023-07-01`.
required: false
schema:
type: string
format: date
example: 2023-04-01
responses:
'200':
description: all data required to render an indicatorset is returned
content:
application/json:
schema:
$ref: '#/components/schemas/IndicatorSet'
'401':
$ref: '#/components/responses/NoAuth'
'403':
$ref: '#/components/responses/NoAccess'
'404':
description: The provided `setKey` doesn't refer to a valid program.
components:
schemas:
IndicatorSet:
description: |-
A report about a care program based on showing a number of ratios, such as 'how many people in your practice have diabetes', or 'for all diabetes patients in your care with a recent blood pressure measurement, how do these blood pressure measurements split into "problematic" / "concern" / "okay" categories
type: object
properties:
name:
description: Human readable dutch text; should fit in one line.
type: string
example: Diabetes Mellitus type 2 per InEen 2023 accreditatie
refDate:
description: 'All calculations are done on this date (dutch: _peildatum_).'
type: string
format: date
example: 2023-04-01
chapters:
description: Each chapter has a title and contains 1 or more indicators.
type: array
items:
type: object
properties:
title:
description: In dutch, *HTML* formatted; should fit on one line.
type: string
example: Populatie
indicators:
description: The indicators in this chapter
type: array
items:
$ref: '#/components/schemas/Indicator'
Indicator:
description: |-
A single ratio or flat number; should be shown as one box with a chart (generally, a single fixed-size bar with each ratio element rendered on this bar). The numbers in this object are on some axis, generally, percentage.
type: object
properties:
title:
description: Short, in dutch, *HTML* (but rarely includes formatting; at most, sup/superscript).
type: string
example: Prevalentie Diabetes
xMin:
description: Numeric value of the far left of the bar.
type: number
example: 10.0
default: 0
xMax:
description: Numeric value of the far right of the bar.
type: number
example: 80.0
default: 100.0
xLow:
description: |-
*OPTIONAL* If present, draw a bar at this position indicating that this indicator can fall below this lower bound, but if it does, that is noteworthy. For example, because that is beyond 3 standard deviations of the dutch average, or, its a goal set by the practice, the insurer, or the care group and thus falling below it means the goal is not met.
type: number
example: 20.0
xHigh:
description: |-
*OPTIONAL* If present, draw a bar at this position indicating that this indicator can fall above this upper bound, but if it does, that is noteworthy. For example, beyond 3 standard deviations of the dutch average, or, a goal for an indicator where lower is better.
type: number
example: 65.0
unitDesc:
description: |-
*OPTIONAL* describes the unit that the stated legend values are in, in dutch, and *HTML*. For example, if showing blood pressure, `mmHg`. If missing, treat as the empty string (do not show unit at all).
type: string
example: mmHg
default: ''
style:
description: |-
A key that describes the render style for this entire indicator.
For example, 'failed' indicates that the indicator should be rendered
with a red hue to focus the user's attention on the fact that this
indicator represents a goal or requirement that they do not currently
meet.
type: string
example: failed
default: normal
enum:
- failed
- normal
- met
- focus
bars:
description: |-
A series of numbers, each of which needs to be put on the bar in sequence. For some indicators, the sum of the values adds up to be equal to `xMax - xMin`, if it doesn't, the final part of the bar remains blank (white, for example). For example, given the usual xMin/xMax of 0/100, one could have 3 bars: 40-Good, 35-Concern, 25-Problematic. Which should be rendered as green/yellow/red sub-bars of the appropriate size across the indicator.
type: array
items:
type: object
properties:
style:
description: |-
Describes what kind of ratio this bar describes.
Individual bars represent some kind of ratio and this describes the nature of it. Each key should result in some style, generally, the color of the bar. For example, `serious` (indicating a group of patients whose lab result for this indicator is of serious concern, i.e. medically speaking quite bad news) should be rendered dark red.
type: string
example: concern
enum:
- good
- concern
- problem
- serious
- measured
- nonPrefMeasured
- 'TBD: There are many more.'
legend:
description: |-
*OPTIONAL* If present, render the title of this one bar like a legend for a chart. In dutch, *HTML*, and very short.
type: string
example: '≤ 120'
value:
description: |-
The 'size' of the described ratio. Relative to the range of the bar (as described by `xMax`-`xMin`).
type: number
example: 20.5
CareProgram:
type: object
properties:
name:
description: Human readable text in dutch, guaranteed to be quite short.
type: string
example: Diabetes Mellitus type 2 (ZEL)
description:
description: in dutch and in *HTML*, can consist of multiple paragraphs, but won't be more than ~5 lines or so.
type: string
example: Ketenzorg DM2 volgens de standaard werkwijze van zorgggroep ZEL.
defaultShow:
description: If `true`, show this unless explicitly unfavourited. If `false`, do not show unless explicitly favourited.
type: boolean
favState:
description: If `T`, always show this. If `F`, never show it. If `X`, show if `defaultShow` is `true`.
type: string
example: X
enum:
- T
- F
- X
reports:
description: |-
A care program offers 1 or more reports; any given report is generally very different from another.
Each offered report should be shown as a button.
type: array
items:
type: object
properties:
type:
oneOf:
- description: An indicator set report. use the `/qol/indicatorset` API endpoint.
type: string
example: indicatorset
- description: Resolve by loading the URL in the `url` property (`window.location = ` style).
type: string
example: link
name:
description: Short description in dutch text; show this in the button.
type: string
example: Indicatoren
url:
description: >-
Only for `type: "link"`.
type: string
example: '/indicators/casefinder?t=dm'
key:
description: >-
A unique string (always ASCII, no spaces) identifying this care program.
Pass to `/qoc/indicatorset` API, or can be used for fave/unfave.
type: string
example: ZEL-dm2
parameters:
Authorization:
name: Authorization
in: header
description: |-
The string `"Bearer "` followed by a single-use signed JWT token with the following mandatory claims:
<ul>
<li><code>kid</code> <strong>key id</strong>: A string identifying a trusted signer; agreed upon between user and Zorg op Orde beforehand.</li>
<li><code>iat</code> <strong>Issued at</strong>: Time when this JWT was created and signed. Must be no more than 1 hour ago.
<li><code>jti</code> <strong>JWT ID</strong>: A unique string used to prevent replay: Any given ID can not be used more than once.
<li><code>agb</code> <strong>GP AGB</strong>: AGB code (Medical entity identifier); the lookup will be done on the medical dossier data of this practice or entity.
<li><code>exp</code> <em>OPTIONAL</em> <strong>Expires at</strong>: If included, the request must not be received after this time.
<li><code>nbf</code> <em>OPTIONAL</em> <strong>Not before</strong>: If included, the request must not be received before this time.
</ul>
The JWT must be signed, preferably with `HS256`.
required: true
schema:
type: string
example: >-
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJraWQiOiJaT08tQVBJLVBLSS1JRCIsImFnYiI6IjAxMDEyMzQ1IiwiaWF0IjoxNTE2MjM5MDIyLCJqdGkiOiJ0MTIzNC01Njc4LUFCQ0QifQ.wTesCfFTq1Mz8z7hUWU6zzKSc3dopWnpeETR7eDzFtc
responses:
JwtFailure:
description: The JWT token isn't valid or wasn't provided.
content:
application/json:
schema:
type: object
properties:
err:
description: A plain text explanation of what's wrong with the JWT token.
type: string
enum:
- no JWT included
- Unknown signer
- Request sent before nfb
- Request sent after exp
- JWT issued too long ago
- Signature missing
- Signature invalid
- Required claim missing (agb)
- Required claim missing (iat)
- Required claim missing (kid)
- Required claim missing (jti)
- JWT already used
NoAuth:
description: User is not logged in / session expired.
NoAccess:
description: User is not allowed to access this API endpoint.
PatNotFound:
description: Provided filter does not match any patients or no medical dossiers are available for this practice.
content:
application/json:
schema:
type: object
properties:
kind:
description: |-
The 'level' of data that isn't available.<br><ul>
<li>`patient` indicates that there is medical dossier data available for this GP but the patient that is requested cannot be found.</li>
<li>`practice` No medical dossier data is available whatsoever for this practice; either that practice isn't registered or hasn't (yet) provided medical dossier data.</li>
</ul>
type: string
example: practice
enum:
- practice
- patient