Skip to content

Getting Started

Introduction

This is a REST API for healthcare facility information. The most important endpoints deal with health information such as medical-patients, medical-encounters, and medical-records.

There are also several endpoints dealing with information for different modules of healthcare facility management, such as billing information (Clinic/Hospital Billing), diagnostic information (LIS/RIS), inventory information (Materials Management, Point of Sales), among others.

Authentication

Most resources/APIs require authorization before the requests can be resolved. This authorization can be achieved by requesting an access_token (logging in) using the authentication API and sending that access_token for every request made

example:

sh
# Login
curl <base-uri>/authentication \
-X POST \
-H "Content-Type: application/json" \
-d "{
  "email": "email@domain.com",
  "password": "supersecretpass",
}"

# Response
{
  "uid": "some-uid",
  // save this access token
  "accessToken": "ejsdasd.long-token-string.here",
}

# For every authentication-required requests,
# attach the access token
curl <base-uri>/personal-details/some-uid \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "maritalStatus": "single",
}"
# Login
curl <base-uri>/authentication \
-X POST \
-H "Content-Type: application/json" \
-d "{
  "email": "email@domain.com",
  "password": "supersecretpass",
}"

# Response
{
  "uid": "some-uid",
  // save this access token
  "accessToken": "ejsdasd.long-token-string.here",
}

# For every authentication-required requests,
# attach the access token
curl <base-uri>/personal-details/some-uid \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "maritalStatus": "single",
}"

Query Params

Certain query parameter values must be prefixed with the number sign (#) in order to cast them to the required type. i.e.:

  1. numbers; e.g.
sh
# skipping 5 fixtures for the listing operation
curl 'https://api.example.com/fixtures?$skip=#5'
# skipping 5 fixtures for the listing operation
curl 'https://api.example.com/fixtures?$skip=#5'
  1. boolean (true | false)
sh
# filtering fixtures with statuses
curl 'https://api.example.com/fixtures?status[$exists]=#true'
# filtering fixtures with statuses
curl 'https://api.example.com/fixtures?status[$exists]=#true'
  1. empty array ([])
sh
# filtering tags with empty array
curl 'https://api.example.com/fixtures?tags=#[]'
# filtering tags with empty array
curl 'https://api.example.com/fixtures?tags=#[]'

Example:

sh
# Login
curl <base-uri>/authentication \
-X POST \
-H "Content-Type: application/json" \
-d "{
  "email": "email@domain.com",
  "password": "supersecretpass",
}"

# Response
{
  "uid": "some-uid",
  // save this access token
  "accessToken": "ejsdasd.long-token-string.here",
}

# For every authentication-required requests,
# attach the access token
curl <base-uri>/personal-details/some-uid \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "maritalStatus": "single",
}"
# Login
curl <base-uri>/authentication \
-X POST \
-H "Content-Type: application/json" \
-d "{
  "email": "email@domain.com",
  "password": "supersecretpass",
}"

# Response
{
  "uid": "some-uid",
  // save this access token
  "accessToken": "ejsdasd.long-token-string.here",
}

# For every authentication-required requests,
# attach the access token
curl <base-uri>/personal-details/some-uid \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "maritalStatus": "single",
}"

Operators

Some query parameters are special in that they are used as operators

History operator ($history) - when used in GET method

If supported, uses the history collection of a service instead of it's main collection to perform the needed method.

sh
# list history of invoices. Notice the octotorphe (#) on the query param
# value in order to properly convert it to boolean
curl <base-uri>/billing-invoices/<invoice-id>?$history=#true
# list history of invoices. Notice the octotorphe (#) on the query param
# value in order to properly convert it to boolean
curl <base-uri>/billing-invoices/<invoice-id>?$history=#true

History operator ($history) - when used in PATCH method

If supported, restores a history entry from the history collection into the main collection

sh
# list history of invoices. Notice the octotorphe (#) on the query param
# value in order to properly convert it to boolean
curl <base-uri>/billing-invoices/<invoice-id>?$history=#true \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "_record": "entry._record",
}"
# list history of invoices. Notice the octotorphe (#) on the query param
# value in order to properly convert it to boolean
curl <base-uri>/billing-invoices/<invoice-id>?$history=#true \
-X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <captured-accessToken-here>" \
-d "{
  "_record": "entry._record",
}"

Populate operator ($populate)

Used to "populate" or expand reference ids in query results into the actual referenced object in a different service

config fields

  • localKey: string - the field where the itermediate variable 'ids: string | object | string[] | object[]' will be extracted
  • extractKey: string - extract this key from the ids. use for objects or array of objects`
  • skipEmpty: boolean - return [] or null for empty ids field
  • service: string - the service to use
  • method: string - the querying method to use. possible values: find, findOne, get
  • foreignKey: string - the query key where ids will be put. use by methods: find and findOne
  • foreignOps: string - the mongodb operator to use with querying
  • ...restQuery: extra keys in the config

internally, the process goes like

javascript
let ids = parentItem[localKey]
if (extractKey && isPlainObject(ids)) ids = ids[extractKey]
if (extractKey && isArrayOfPlainObject(ids)) ids = ids.map(o => o[extractKey])
if (skipEmpty && (!ids || (isArray(ids) && !ids.length))) return method === 'get' ? null : []
if (method === 'get') return service.get(ids)
if (method === 'find') return service.find({ [foreignKey]: foreignOps ? { [foreignOps]: ids } : ids, ...restQuery })
if (method === 'findOne') return service.findOne({ [foreignKey]: foreignOps ? { [foreignOps]: ids } : ids, ...restQuery })
let ids = parentItem[localKey]
if (extractKey && isPlainObject(ids)) ids = ids[extractKey]
if (extractKey && isArrayOfPlainObject(ids)) ids = ids.map(o => o[extractKey])
if (skipEmpty && (!ids || (isArray(ids) && !ids.length))) return method === 'get' ? null : []
if (method === 'get') return service.get(ids)
if (method === 'find') return service.find({ [foreignKey]: foreignOps ? { [foreignOps]: ids } : ids, ...restQuery })
if (method === 'findOne') return service.findOne({ [foreignKey]: foreignOps ? { [foreignOps]: ids } : ids, ...restQuery })

usage

javascript
// populate the patient and invoice field on the server
const encounters = await sdk.mf.encounters().find({
   facility: 'facility-id',
   $active: true,
   $populate: {
      // will populate (on the result) field '$populated._patient'
      // by querying service `patients` using the key `patient` on the result
      _patient: { service: 'medical-patients', key: 'patient' },
      _invoice: { service: 'billing-invoices', key: 'id' }
  }
})
// populate the patient and invoice field on the server
const encounters = await sdk.mf.encounters().find({
   facility: 'facility-id',
   $active: true,
   $populate: {
      // will populate (on the result) field '$populated._patient'
      // by querying service `patients` using the key `patient` on the result
      _patient: { service: 'medical-patients', key: 'patient' },
      _invoice: { service: 'billing-invoices', key: 'id' }
  }
})

Pre Query (AND|OR) operator ($prequery and $prequeryOr)

Pre-queries that are executed in the server-side that eventually will modify the main query. Mainly used for filtering using multiple services. This adds the result of the pre-queryies in the $or part of the main query (which is added if not exist)

config fields

  • service: string - the service to use
  • query: object | string - the query to use. result will be put to an itermediate variable 'items: object | object[]'
  • extractKey: string - extract this key from the variable items
  • localKey: string - the query key where items will be put
  • localOps: string - the mongodb operator to use with querying

internally, the process goes like

javascript
let items = isPlainObject(query) ? service.find(query) : service.get(query)
if (isPlainObject(items)) items = items[extractKey]
if (isArrayOfPlainObject(items)) items = items.map(i => i[extractKey])
if ($prequery) return parentQuery.$and.push({ [localKey]: localOps ? { [localOps]: items } : items })
if ($prequeryOr) return parentQuery.$or.push({ [localKey]: localOps ? { [localOps]: items } : items })
let items = isPlainObject(query) ? service.find(query) : service.get(query)
if (isPlainObject(items)) items = items[extractKey]
if (isArrayOfPlainObject(items)) items = items.map(i => i[extractKey])
if ($prequery) return parentQuery.$and.push({ [localKey]: localOps ? { [localOps]: items } : items })
if ($prequeryOr) return parentQuery.$or.push({ [localKey]: localOps ? { [localOps]: items } : items })

usage

javascript
// find invoices in the facility w/c have items
// that are covered by the specified hmo
// in a date range
const invoices = await sdk.billing.invoices().find({
   // limit to facility
   facility: 'facility-id',
   // query only the finalized invoices
   finalizedAt: { $exists: true },
   // where the dates can be any date format
   createdAt: { $gte: currentDate, $lte: addDays(currentDate, 1) },
   // modifies the final query
   $prequery: [
     {
       // find billing items w/c are covered
       // by a specific hmo
       service: 'billing-items',
       query: {
         facility: 'facility-id',
         coverages: {
           contract: 'hmo-contract-id',
           // or insurer: 'hmo-org-id'
         }
       },
       // extract the invoice of the resulting items (for limiting query to only these invoices)
       extractKey: 'invoice',
       // modify the final query
       // by adding an $and clause with these values
       resKey: 'id',
       resOps: '$in'
     }
   ]
});


// find invoices in the facility where the attached
// encounter has the specified doctor
const invoices = await sdk.billing.invoices().find({
   facility: 'facility-id',
   // modifies the final query
   $prequery: [
     {
       // find an encounter with the specified doctor
       service: 'medical-encounters',
       query: { facility: 'facility-id', doctors: 'some-doctor-uid' },
       // extract the id of the resulting encounters
       extractKey: 'id',
       // modify the final query
       // by adding an $and clause with these values
       resKey: 'id',
       resOps: '$in'
     }
   ]
});

// final query form, assuming and encounter was found
{
  facility: 'facility-id',
  $and: [
    // where 'id' field was from the 'resKey' and '$in' from resOps
    // ['encounter-with-doc-id'] was the result of extracting 'resKey' from the result of the prequery
    { id: { $in: ['encounter-with-doc-id'] } }
  ]
}
// find invoices in the facility w/c have items
// that are covered by the specified hmo
// in a date range
const invoices = await sdk.billing.invoices().find({
   // limit to facility
   facility: 'facility-id',
   // query only the finalized invoices
   finalizedAt: { $exists: true },
   // where the dates can be any date format
   createdAt: { $gte: currentDate, $lte: addDays(currentDate, 1) },
   // modifies the final query
   $prequery: [
     {
       // find billing items w/c are covered
       // by a specific hmo
       service: 'billing-items',
       query: {
         facility: 'facility-id',
         coverages: {
           contract: 'hmo-contract-id',
           // or insurer: 'hmo-org-id'
         }
       },
       // extract the invoice of the resulting items (for limiting query to only these invoices)
       extractKey: 'invoice',
       // modify the final query
       // by adding an $and clause with these values
       resKey: 'id',
       resOps: '$in'
     }
   ]
});


// find invoices in the facility where the attached
// encounter has the specified doctor
const invoices = await sdk.billing.invoices().find({
   facility: 'facility-id',
   // modifies the final query
   $prequery: [
     {
       // find an encounter with the specified doctor
       service: 'medical-encounters',
       query: { facility: 'facility-id', doctors: 'some-doctor-uid' },
       // extract the id of the resulting encounters
       extractKey: 'id',
       // modify the final query
       // by adding an $and clause with these values
       resKey: 'id',
       resOps: '$in'
     }
   ]
});

// final query form, assuming and encounter was found
{
  facility: 'facility-id',
  $and: [
    // where 'id' field was from the 'resKey' and '$in' from resOps
    // ['encounter-with-doc-id'] was the result of extracting 'resKey' from the result of the prequery
    { id: { $in: ['encounter-with-doc-id'] } }
  ]
}

Released under the MIT License.