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
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:
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.
{
"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.
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
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.
TelePharm considers backwards compatible changes to include any of the following:
Use the /fills
endpoint to notify TelePharm of information or workflow change related to a prescription fill
locationId required | string a stored location id from the initial interface configuration (GET |
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 |
{- "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": {
- "fillNumber": 2,
- "prescriptionNumber": "521401",
- "quantityPrescribed": 30,
- "refillsAuthorized": 2,
- "dawCode": 1,
- "prn": false,
- "writtenDate": "2018-11-25",
- "expireDate": "2019-11-25",
- "originCode": 1
}, - "drug": {
- "ndc": "50580044909",
- "name": "Tylenol",
- "genericName": "string",
- "substitutionFor": "string",
- "strength": "325",
- "strengthUnitOfMeasure": "mg",
- "manufacturer": "string",
- "packageSize": "string",
- "frontImprint": "string",
- "backImprint": "string",
- "schedule": "1"
}, - "patient": {
- "externalId": "1234",
- "firstName": "Bobby",
- "lastName": "Tables",
- "middleName": "",
- "gender": "male",
- "species": "human",
- "easyCapsPreferred": true,
- "ssn": "string",
- "dateOfBirth": "2019-08-24",
- "medicaidNumber": "string",
- "medicareNumber": "string",
- "emails": [
- "string"
], - "phones": [
- {
- "type": "home",
- "phone": "444-444-4444"
}
], - "addresses": [
- {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
], - "language": "string",
- "noKnownAllergies": true,
- "allergies": [
- {
- "category": "medication",
- "type": "allergy",
- "code": "Amoxicillin",
- "description": "string",
- "reaction": "Causes hives",
- "severity": "low",
- "onSetDate": "2019-08-24"
}
]
}, - "prescriber": {
- "externalId": "string",
- "firstName": "Jane",
- "lastName": "Doe",
- "middleName": "string",
- "prefix": "string",
- "suffix": "MD",
- "phones": [
- {
- "type": "home",
- "phone": "444-444-4444"
}
], - "addresses": [
- {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
], - "fax": "string",
- "deaNumber": "string",
- "npiNumber": "string"
}, - "location": {
- "externalId": "string",
- "name": "West Side Pharmacy",
- "npiNumber": "string",
- "ncpdp": "1111111",
- "description": "string",
- "address": {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
}, - "transaction": {
- "copay": "5.50",
- "discount": "string",
- "tax": "string",
- "acquisitionCost": "string",
- "adjustedWholesalePrice": "string",
- "totalCost": "string",
- "totalBilled": "string",
- "totalInsurancePaid": "string",
- "appliedFees": [
- {
- "amount": "string",
- "description": "string"
}
]
}, - "metadata": {
- "sendingApplication": "string",
- "operator": "string",
- "fillVersion": "string"
}, - "warnings": [
- {
- "language": "en-us",
- "text": "string"
}
], - "directions": [
- {
- "language": "en-us",
- "text": "Take 2 tablets as needed for pain"
}
], - "comments": [
- {
- "type": "Fill",
- "authorReference": "string",
- "authorString": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "text": "string"
}
], - "dur": [
- {
- "conflictName": "string",
- "description": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "interactionNumber": 0,
- "durOverridden": true,
- "prescriptionNumber": "string",
- "severityCode": "string",
- "severityCodeDecoded": "string",
- "typeCode": "string",
- "typeCodeDecoded": "string"
}
]
}
{- "id": 53
}
Use the /action endpoint to perform an action on a Telepharm fill
locationId required | string a stored location id from the initial interface configuration (GET |
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" |
{- "externalId": "string",
- "action": "SOLD"
}
{- "id": 53
}
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.
locationId required | string a stored location id from the initial interface configuration (GET |
an array of json objects 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 |
[- {
- "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": {
- "fillNumber": 2,
- "prescriptionNumber": "521401",
- "quantityPrescribed": 30,
- "refillsAuthorized": 2,
- "dawCode": 1,
- "prn": false,
- "writtenDate": "2018-11-25",
- "expireDate": "2019-11-25",
- "originCode": 1
}, - "drug": {
- "ndc": "50580044909",
- "name": "Tylenol",
- "genericName": "string",
- "substitutionFor": "string",
- "strength": "325",
- "strengthUnitOfMeasure": "mg",
- "manufacturer": "string",
- "packageSize": "string",
- "frontImprint": "string",
- "backImprint": "string",
- "schedule": "1"
}, - "patient": {
- "externalId": "1234",
- "firstName": "Bobby",
- "lastName": "Tables",
- "middleName": "",
- "gender": "male",
- "species": "human",
- "easyCapsPreferred": true,
- "ssn": "string",
- "dateOfBirth": "2019-08-24",
- "medicaidNumber": "string",
- "medicareNumber": "string",
- "emails": [
- "string"
], - "phones": [
- {
- "type": "home",
- "phone": "444-444-4444"
}
], - "addresses": [
- {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
], - "language": "string",
- "noKnownAllergies": true,
- "allergies": [
- {
- "category": "medication",
- "type": "allergy",
- "code": "Amoxicillin",
- "description": "string",
- "reaction": "Causes hives",
- "severity": "low",
- "onSetDate": "2019-08-24"
}
]
}, - "prescriber": {
- "externalId": "string",
- "firstName": "Jane",
- "lastName": "Doe",
- "middleName": "string",
- "prefix": "string",
- "suffix": "MD",
- "phones": [
- {
- "type": "home",
- "phone": "444-444-4444"
}
], - "addresses": [
- {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
], - "fax": "string",
- "deaNumber": "string",
- "npiNumber": "string"
}, - "location": {
- "externalId": "string",
- "name": "West Side Pharmacy",
- "npiNumber": "string",
- "ncpdp": "1111111",
- "description": "string",
- "address": {
- "type": "home",
- "line1": "123 Sesame St",
- "line2": "Apt 5",
- "city": "New York",
- "state": "New York",
- "zip": "12345-1234"
}
}, - "transaction": {
- "copay": "5.50",
- "discount": "string",
- "tax": "string",
- "acquisitionCost": "string",
- "adjustedWholesalePrice": "string",
- "totalCost": "string",
- "totalBilled": "string",
- "totalInsurancePaid": "string",
- "appliedFees": [
- {
- "amount": "string",
- "description": "string"
}
]
}, - "metadata": {
- "sendingApplication": "string",
- "operator": "string",
- "fillVersion": "string"
}, - "warnings": [
- {
- "language": "en-us",
- "text": "string"
}
], - "directions": [
- {
- "language": "en-us",
- "text": "Take 2 tablets as needed for pain"
}
], - "comments": [
- {
- "type": "Fill",
- "authorReference": "string",
- "authorString": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "text": "string"
}
], - "dur": [
- {
- "conflictName": "string",
- "description": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "interactionNumber": 0,
- "durOverridden": true,
- "prescriptionNumber": "string",
- "severityCode": "string",
- "severityCodeDecoded": "string",
- "typeCode": "string",
- "typeCodeDecoded": "string"
}
]
}
]
[- {
- "id": 53
}
]
Add images to a specified fill
locationId required | string a stored location id from the initial interface configuration (GET |
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 |
The request body should contain binary image content
{- "id": 53,
- "createdAt": "string"
}
Get count only images from a specified prescription fill
locationId required | integer a stored location id from the initial interface configuration (GET |
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 |
fromPMS | boolean Add query parameter |
[- {
- "imageId": "kf06e5f7-19df-4nb8-a7e8-525882204700",
- "expiration": "2023-12-30T12:00:00.000Z",
}
]
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.
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.
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")