TelePharm API (v1)

Download OpenAPI specification:Download

The TelePharm API allows companies to extend their Pharmacy Data Solution with additional Telepharmacy capabilities. The API is set up to operate on RESTful constructs. Primarily, it relies on the creation of various workflow events occuring within a Pharmacy Data System. All API endpoints accept and respond using JSON structured data and HTTP Status Codes, unless otherwise mentioned.

 


 

To facilitate development, a sample endpoint with test credentials can be issued upon request. A sample environment will effectively provide a sandbox for creating workflow events. To provide services in production, any product connecting to the TelePharm API should accept an API key and endpoint as a configuration option from the user.

If you have questions, please contact our support email

Integration Overview

 

Client:

A client application is required to interact with a TelePharm API endpoint. This is typically a supported pharmacy data system, or server. The integration can interact with one or many location's resources.

Receiving events from TelePharm

When events occur in TelePharm, they can be communicated back to the integrating system. There are two ways to receive these events:

  1. A Client TLS Websocket (WSS) connection
  2. A webhook sent to an HTTPS endpoint

It is up to the implementer to choose which method is preferred. Only one of the two options is required.

Connecting via websockets, or registering a webhook and secret with TelePharm, enables an integrating system to receive updates about activity occurring in the TelePharm workflow. Eg. Filled, Verified, events, etc. This can be useful to ensure continuity of workflow between different software in the pharmacy environment.

  • Websocket and Webhook Payload (JSON Schema)
    {
      "type": "object",
      "properties": {
          "messageId": {
              "type": "string",
              "pattern": "^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$",
              "description": "unique event message identifier"
          },
          "event": {
              "oneOf": [
                  {
                      "const": "FillVerified",
                      "description": "will only be triggered for a location with PV1 enabled in TelePharm and signals that the prescription has passed a PV1 check"
                  },
                  {
                      "const": "FillApproved",
                      "description": "the pharmacist approved the prescription (PV2) and it is now in will call and can be given to the patient."
                  },
                  {
                      "const": "FillDispensed",
                      "description": "the prescription has been dispensed to the patient and is no longer awaiting pickup"
                  },
                  {
                      "const": "FillRejected",
                      "description": "the pharmacist rejected the prescription"
                  },
                  {
                      "const": "GFDReviewed",
                      "description": "the pharmacist reviewed the good faith dispensing information attached to the prescription"
                  },
                  {
                      "const": "FillCounted",
                      "description": "the count has been completed"
                  },
                  {
                      "const": "FillSubmitted",
                      "description": "the fill has been submitted to pending status"
                  }
              ]
          },
          "prescriptionNumber": {
              "type": "string",
              "description": "Prescription number (equivalent to `fill.script.prescriptionNumber` from the `/fills` resource"
          },
          "externalId": {
              "type": "string",
              "description": "System fill identifier (equivalent to `fill.externalId`, from the `/fills` resource"
          },
          "operator": {
              "type": [
                  "string",
                  "null"
              ],
              "description": "External System Identifier or text, for correlating and identifying user actions"
          },
          "operatorName": {
              "type": [
                  "string",
                  "null"
              ],
              "description": "Full name of the operator who performed the action"
          },
          "operatorLocationId": {
              "type": [
                  "string",
                  "null"
              ],
              "description": "Current location/site system identifier of the operator who performed the action"
          },
          "locationId": {
              "type": "string",
              "description": "System unique location/site identifier (equivalent to `fill.location.externalId` or `fill.location.ncpdp` from the `/fills` resource"
          },
          "createdAt": {
              "type": "string",
              "format": "date-time",
              "description": "Time the event occurred, ISO 8601 (UTC) datetime string"
          },
          "tpImageData": {
              "type": [
                  "array",
                  "null"
              ],
              "items": {
                  "type": "object",
                  "properties": {
                      "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Time the image url was created"
                      },
                      "count": {
                          "type": "integer",
                          "description": "Number of pills counted in the image"
                      },
                      "signedUrl": {
                          "type": "string",
                          "description": "URL to the image of the package, signed with a temporary token"
                      },
                      "lotNumber": {
                          "type": "string",
                          "description": "Lot number of the package"
                      },
                      "lotExpiration": {
                          "type": "string",
                          "description": "Expiration date of the package"
                      },
                      "lotExpired": {
                          "type": "boolean",
                          "description": "Indicates if the package is expired"
                      }
                  },
                  "required": [
                      "createdAt",
                      "signedUrl"
                  ]
              },
              "description": "Array of images taken during the fill process, including count and not count images, tpImageData information is only going to be available for FillCounted, FillApproved, and FillSubmitted events"
          }
      },
      "required": [
          "messageId",
          "event",
          "prescriptionNumber",
          "externalId",
          "operator",
          "operatorName",
          "operatorLocationId",
          "locationId",
          "createdAt",
          "tpImageData"
      ],
      "additionalProperties": false
    }

Note: A websocket client should be able to receive more than the three "event" types documented here, whose event payloads can safely be discarded.

To subscribe to these notifications the following payload can be sent over a connected websocket (specifying the correct/desired locationIds)

   {
     "action": "Join",
     "channel": "FillEvents",
     "locationIds": [1]
   }

In response, one or many Joined events will be returned.

Authentication

 

You can authenticate any request by including your secret API Key. API keys are managed by TelePharm Users and any implementation should accept an API key as a configuration option. A key should be kept secret, and should not be stored on the client side or on an insecure machine. To make an authenticated request, provide an HTTP header similar to the following:

 

Authorization: Bearer t3sample_*FTEkDm-2-3YA5uj_vhcgHQ*GVxypZKNcch8TZplXxHRlw***y7_77e1r_MDmEDOC6nCII7K3O-qULqaDLOa_7V-Svi0

 

Versioning

 

The version of the API being used is directly visible in the URL of any API endpoint. For example Version 1 of the API has a base route accessible at https://<api-root>/v1.

 

Any backwards compatible changes, such as the addition of fields, should be supported by any implementation. Backwards incompatible changes will always result in a version increment.

 

Backwards Compatible Changes:

TelePharm considers backwards compatible changes to include any of the following:

  • Adding additional properties to existing resources
  • Adding new API Resources
  • Changing object size (eg. strings may be longer than 255 bytes)
  • Changing the order of keys in a JSON object.
  • Accepting additional (optional) parameters to API endpoints
  • Creating new webhook and event types

Locations

getLocations

Get a list of available locations. An integration will interact with at least one location's resources

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Fills

createFill

Use the /fills endpoint to notify TelePharm of information or workflow change related to a prescription fill

path Parameters
locationId
required
string

a stored location id from the initial interface configuration (GET /locations)

Request Body schema: application/json

a json object describing the fill and related information

externalId
required
string

Unique system identifier for this fill, eg. Transaction, or work-item id

daysSupply
integer >= 0

Number of days the quantity being dispensed should last

quantityDispensed
required
number >= 0

Quantity being dispensed for this fill

quantityDispensedToDate
required
number >= 0

Total quantity dispensed to date for this prescription. This value is zero for the initial fill.

dosage
string

Description of the quantity to be taken

easyCap
boolean

EasyCap Indicator

counselingRequired
boolean

Indicate if counseling is required or not required for this fill

centralFill
boolean

Indicate if the fill was assembled by a central fill site

promisedTime
string or null <date-time>

Time indicated for pickup / ready time

originalFillDate
string or null <date>

Date the prescription was originally filled (if transferred)

refillDueDate
string or null <date>

Next refill date

createdDate
string or null <date-time>

Date of this event

action
required
string
Enum: "Profile" "Fill" "Approve" "InsuranceBilled" "InsuranceRejected" "Update" "Complete" "Restock" "Cancel" "Void" "Discontinue" "Historical"

The event occurring on or for this fill

required
object (ApiScript)
required
object (Drug)
required
object (Patient)
object (Prescriber)
required
object (Location)
required
object (Transaction)
required
object (FillMetadata)
Array of objects (Warning)
Array of objects (Direction)
Array of objects (Comment)
Array of objects or null

Responses

Request samples

Content type
application/json
{
  • "externalId": "123",
  • "daysSupply": 30,
  • "quantityDispensed": 30,
  • "quantityDispensedToDate": 0,
  • "dosage": "2 tablets",
  • "easyCap": true,
  • "counselingRequired": false,
  • "centralFill": false,
  • "promisedTime": "2019-04-12T23:20:50.52Z",
  • "originalFillDate": "2019-04-12",
  • "refillDueDate": "2019-08-24",
  • "createdDate": "2018-04-12T13:15:50.52Z",
  • "action": "Fill",
  • "script": {
    },
  • "drug": {
    },
  • "patient": {
    },
  • "prescriber": {
    },
  • "location": {
    },
  • "transaction": {
    },
  • "metadata": {
    },
  • "warnings": [
    ],
  • "directions": [
    ],
  • "comments": [
    ],
  • "dur": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 53
}

performAction

Use the /action endpoint to perform an action on a Telepharm fill

path Parameters
locationId
required
string

a stored location id from the initial interface configuration (GET /locations)

Request Body schema: application/json

a json object that designates the fill by external id along with the action to perform

externalId
required
string
action
required
string
Enum: "SOLD" "DELETE" "PRINT" "READY" "PMNTU"

Responses

Request samples

Content type
application/json
{
  • "externalId": "string",
  • "action": "SOLD"
}

Response samples

Content type
application/json
{
  • "id": 53
}

createFillHistory

Use the /fills/history endpoint to import fills as a location goes live or to send a patient's fill history. Fills can be mapped to active stages using the action key. Can accept up to 100 fills in one request.

path Parameters
locationId
required
string

a stored location id from the initial interface configuration (GET /locations)

Request Body schema: application/json

an array of json objects describing the fill and related information

Array
externalId
required
string

Unique system identifier for this fill, eg. Transaction, or work-item id

daysSupply
integer >= 0

Number of days the quantity being dispensed should last

quantityDispensed
required
number >= 0

Quantity being dispensed for this fill

quantityDispensedToDate
required
number >= 0

Total quantity dispensed to date for this prescription. This value is zero for the initial fill.

dosage
string

Description of the quantity to be taken

easyCap
boolean

EasyCap Indicator

counselingRequired
boolean

Indicate if counseling is required or not required for this fill

centralFill
boolean

Indicate if the fill was assembled by a central fill site

promisedTime
string or null <date-time>

Time indicated for pickup / ready time

originalFillDate
string or null <date>

Date the prescription was originally filled (if transferred)

refillDueDate
string or null <date>

Next refill date

createdDate
string or null <date-time>

Date of this event

action
required
string
Enum: "Profile" "Fill" "Approve" "InsuranceBilled" "InsuranceRejected" "Update" "Complete" "Restock" "Cancel" "Void" "Discontinue" "Historical"

The event occurring on or for this fill

required
object (ApiScript)
required
object (Drug)
required
object (Patient)
object (Prescriber)
required
object (Location)
required
object (Transaction)
required
object (FillMetadata)
Array of objects (Warning)
Array of objects (Direction)
Array of objects (Comment)
Array of objects or null

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Response samples

Content type
application/json
[
  • {
    }
]

Images

addImage

Add images to a specified fill

path Parameters
locationId
required
string

a stored location id from the initial interface configuration (GET /locations)

fillId
required
string

the id of the fill that the image will be attached to

category
required
string
Enum: "script" "label" "bottle" "drug" "extra" "autocrop" "delivery" "count"

an image category: script,label,bottle,drug,extra,autocrop,delivery,count

Request Body schema:

The request body should contain binary image content

string <binary>

Responses

Response samples

Content type
application/json
{
  • "id": 53,
  • "createdAt": "string"
}

getImages

Get count only images from a specified prescription fill

path Parameters
locationId
required
integer

a stored location id from the initial interface configuration (GET /locations)

rxNumber
required
integer

rx number of the fill the image is attached to

fillNumber
required
integer

fill number provided by the PMS during fill creation, or fill number included in the API during fill creation or fill number calculated by TelePharm

query Parameters
fromPMS
boolean

Add query parameter fromPMS to get images only if prescription was created from PMS, ignore otherwise

Responses

Response samples

Content type
application/json
[]

Websockets

To make a websocket connection, you must first acquire a wssUrl. This can be done by making a POST request to the /connect endpoint. The returned object will contain a wssUrl, which you can then use to connect your websocket client. This wssUrl will be valid for one websocket connection.

In order to reconnect after a network error or intentional disconnect, the client must request an updated wssUrl from the /connect endpoint.

Post to the connect endpoint to receive a websocke

Post to the connect endpoint to receive a websocket connection url

Responses

Response samples

Content type
application/json
{
  • "wssUrl": "wss://example.com?token=123345"
}

Webhooks

A web server is optional, and only required if webhook resources are used to receive events from TelePharm. This will facilitate unsolicited status updates from the TelePharm API. TelePharm will POST to a provided HTTPS endpoint when relevant events occur within the Telepharmacy workflow.

Currently, all webhooks must be registered with our integration team. A webhook must be a publicly addressable https URL.

Validating incoming webhook requests

When a hook is received, its authenticity can be verified by comparing the value in the X-Webhook-Signature header with a calculated value.

This value will be a base64 encoded HMAC-SHA256 of the sum of the request body and date header, keyed with shared secret that was created along with the hook

Comparing the calculated value with the received value will ensure an authentic request was received.

var payload_bytes = Bytes.Concat(request_headers.Get('date'), request_body)
var sig = Base64(Hmac256(payload_bytes, hook_secret))
var is_authentic_request = sig == request_headers.Get("x-webhook-signature")