Skip to main content

Getting Started with DoseSpot

This guide explains how to sync the relevant resources between Medplum and DoseSpot. It is all integrated into the Provider App already, but these instructions will show you how to use the hooks and bots in your own application.

info

This is a premium tier 3rd party integration feature. Please contact us at support@medplum.com to get access.

Authentication​

To use any of the hooks or Bots, you will first need to add your DoseSpot clinician id as an identifier to each User's ProjectMembership. Please contact Medplum support to get your DoseSpot clinician id.

{
"resourceType": "ProjectMembership",
"id": "123",
"project": {
"reference": "Project/123"
},
"user": {
"reference": "User/123"
},
"identifier": [
{
"system": "https://my.staging.dosespot.com/webapi/v2/",//https://my.dosespot.com/webapi/v2/ for production
"value": "123456"
}
],
}

Syncing Prescriptions​

Syncing Active Prescriptions - DoseSpot Prescription Sync Bot​

Prescriptions that were prescribed in DoseSpot can be synced back to Medplum by using the DoseSpot Prescription Sync Bot.

The Bot will create or update MedicationRequest resources in Medplum for the specified date range and patient.

Example of executing the bot:

const DOSESPOT_PRESCRIPTIONS_SYNC_BOT: Identifier = {
system: 'https://www.medplum.com/bots',
value: 'dosespot-prescriptions-sync-bot',
};

const medicationRequests = await medplum.execute(DOSESPOT_PRESCRIPTIONS_SYNC_BOT, {
patientId,
start: "2023-01-01",
end: "2025-01-01",
//raw: true //returns raw DoseSpot prescription data instead of creating and returning MedicationRequest resources
}) as MedicationRequest[];

For a more thorough example implementing this bot, see the Provider App's DoseSpotAdvancedOptions.

Example of the MedicationRequest resource that could be created or updated by the bot
{
"resourceType": "MedicationRequest",
"id": "123",
"identifier": [
{
"system": "https://dosespot.com/prescription-id",
"value": "459848468"
}
],
"status": "completed",
"statusReason": {
"coding": [
{
"system": "https://dosespot.com/medication-status",
"code": "Completed",
"display": "Completed"
}
]
},
"extension": [
{
"url": "https://dosespot.com/prescription-status",
"valueCode": "PharmacyVerified"
}
],
"intent": "order", // designates this as an active prescription ordered in DoseSpot
"medicationCodeableConcept": {
"coding": [
{
"system": "http://hl7.org/fhir/sid/ndc",
"code": "57896059815"
}
],
"text": "Lip-Care External Stick"
},
"subject": {
"reference": "Patient/123",
"display": "John Doe"
},
"authoredOn": "2025-05-06T23:43:01.483",
"recorder": {
"identifier": {
"value": "dosespot"
}
},
"dispenseRequest": {
"validityPeriod": {
"start": "2025-05-06T23:43:01.483"
},
"quantity": {
"value": 2,
"unit": "Stick",
"system": "http://unitsofmeasure.org"
},
"expectedSupplyDuration": {
"value": 1,
"unit": "days",
"system": "http://unitsofmeasure.org",
"code": "d"
}
}
//...
}

Understanding the Prescription Status​

MedicationRequests that represent active prescriptions from DoseSpot capture status information in three different fields:

1. MedicationRequest.status​

Medplum's interpretation of the prescription status, mapped to MedicationRequest.status codes.

See the full list of status codes
statusDescription
activeThe prescription is active.
on-holdThe prescription is on hold.
cancelledThe prescription has been cancelled.
completedThe prescription has been completed.
entered-in-errorThe prescription has been entered in error.
stoppedThe prescription has been stopped.
draftThe prescription is a draft.
unknownThe status of the prescription is unknown.

2. MedicationRequest.statusReason (system: https://dosespot.com/medication-status)​

DoseSpot's status for the prescription. This is what determines MedicationRequest.status.

See the full list of statusReason codes
codeDescription
ActiveThe prescription is active.
DiscontinuedThe prescription has been discontinued.
DeletedThe prescription has been deleted.
CompletedThe prescription has been completed.
CancelRequestedThe prescription has been requested to be cancelled.
CancelPendingThe prescription has been cancelled.
CancelledThe prescription has been cancelled.
CancelDeniedThe prescription has been cancelled.
ChangedThe prescription has been changed.
FullFillThe prescription has been fully filled.
PartialFillThe prescription has been partially filled.
NoFillThe prescription has not been filled.

3. MedicationRequest.extension (url: https://dosespot.com/prescription-status)​

DoseSpot's more granular transmission status for this specific Rx Order.

See the full list of MedicationRequest.extension codes
valueCodeDescription
EnteredThe prescription has been entered.
PrintedThe prescription has been printed.
SendingThe prescription is currently being sent.
eRxSentThe prescription has been sent via eRx.
ErrorThe prescription has an error.
DeletedThe prescription has been deleted.
RequestedThe prescription has been requested.
EditedThe prescription has been edited.
EpcsErrorThe prescription has an Epcs error.
EpcsSignedThe prescription has been signed by Epcs.
ReadyToSignThe prescription is ready to be signed.
PharmacyVerifiedThe prescription has been verified by the pharmacy.

Syncing Med History - DoseSpot Medication History Bot​

This bot gives you the ability to sync prescription history from SureScripts back to Medplum. This includes medication history from other providers that SureScripts has access to.

The Bot will create or update MedicationRequest resources in Medplum for the specified date range and patient.

Please note that when testing with the DoseSpot sandbox, you must use this patient:
{
"resourceType": "Patient",
"name": [
{
"given": [
"Rowena",
"Baylie"
],
"family": "Acacianna"
}
],
"telecom": [
{
"system": "email",
"use": "home",
"value": "example+dosespot@example.com"
},
{
"system": "phone",
"value": "+15052936547",
"use": "mobile"
}
],
"gender": "male",
"birthDate": "1968-03-29",
"address": [
{
"use": "home",
"type": "both",
"line": [
"2798 Parsifal St NE"
],
"city": "Albuquerque",
"state": "NM",
"postalCode": "87112"
}
],
"active": true
}

Example executing the bot:

const DOSESPOT_MEDICATION_HISTORY_BOT: Identifier = {
system: 'https://www.medplum.com/bots',
value: 'dosespot-medication-history-bot',
};

const medicationRequests = await medplum.execute(DOSESPOT_MEDICATION_HISTORY_BOT, {
patientId,
start: "2023-01-01",
end: "2025-01-01",
//raw: true //returns raw DoseSpot prescription data instead of creating and returning MedicationRequest resources
}) as MedicationRequest[];

For a more thorough example implementing this bot, see the Provider App's DoseSpotAdvancedOptions.

Example of a MedicationRequest resource that could be created the bot
{
"resourceType": "MedicationRequest",
"id": "456",
"identifier": [
{
"system": "https://dosespot.com/medication-history-id",
"value": "361242"
}
],
"status": "completed",
"intent": "original-order", //designates this as a medication history, not an prescription intended to be fulfilled
"medicationCodeableConcept": {
"coding": [
{
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": "1190572"
},
{
"system": "http://hl7.org/fhir/sid/ndc",
"code": "00378041501"
}
],
"text": "Diphenoxylate-Atropine 2.5 mg-0.025 mg Tablet"
},
"subject": {
"reference": "Patient/456",
"display": "Rowena Baylie Acacianna"
},
"authoredOn": "2025-03-26T00:00:00",
"recorder": {
"identifier": {
"value": "surescripts"
}
},
"dispenseRequest": {
"validityPeriod": {
"start": "2025-03-26T00:00:00",
"end": "2025-03-26T00:00:00"
},
"quantity": {
"value": 15,
"unit": "Tablet",
"system": "http://unitsofmeasure.org"
},
"expectedSupplyDuration": {
"value": 5,
"unit": "days",
"system": "http://unitsofmeasure.org",
"code": "d"
}
},
"dosageInstruction": [
{
"route": {
"coding": [
{
"system": "https://dosespot.com",
"code": "Oral",
"display": "Oral"
}
]
}
}
],
"reasonCode": [
{
"coding": [
{
"system": "http://hl7.org/fhir/sid/icd-10",
"code": "K591"
}
]
}
],
//...
}

Understanding the Prescription and Medication History Data Flow​

Distinguishing Between Different MedicationRequests​

When working with DoseSpot integration, it's important to understand the different types of MedicationRequests that will be in your Medplum project.

  • MedicationRequest?intent=plan - Self-reported medications. These are used for drug-drug interaction (DDI) checks in DoseSpot. You create these.

  • MedicationRequest?intent=order - Active medication orders that have been prescribed and are currently being filled or taken by the patient. These represent the current active prescriptions. The DoseSpot Prescription Sync Bot creates these.

  • MedicationRequest?intent=original-order - Medication histories from SureScripts and other providers. These represent historical medication data that has been retrieved from external sources. The DoseSpot Medication History Bot creates these.

Enrolling Prescribers​

Summary​

To enroll a prescriber in DoseSpot, you can use the DoseSpot Enroll Prescriber Bot. This bot creates a clinician record in DoseSpot for a Practitioner and automatically adds the DoseSpot clinician ID as an identifier to their ProjectMembership.

Prerequisites​

Before enrolling a prescriber, ensure:

  • The Practitioner resource exists in Medplum
  • The Practitioner has a corresponding ProjectMembership
  • The Practitioner has required information (name, NPI, contact information, etc.)
  • The ProjectMembership does not already have a DoseSpot identifier (the bot will prevent duplicate enrollment)

Required Practitioner Fields​

For successful enrollment, the Practitioner resource must include the following fields:

Required Fields​

  • name (at least one name entry)
    • name.family - Last name (required)
    • name.given - First name (at least one given name required)
  • birthDate - Date of birth
  • address (at least one address)
    • address.line - Street address (at least one line required)
    • address.city - City (required)
    • address.state - State (required)
    • address.postalCode - ZIP/postal code (required)
  • identifier with NPI
    • identifier.system = "http://hl7.org/fhir/sid/us-npi" (required)
    • identifier.value - NPI number (required, must be exactly 10 digits and pass validation)
  • telecom with email (system: "email")
  • telecom with work phone (system: "phone", use: "work")
  • telecom with fax (system: "fax")
NPI Validation

If an NPI identifier is present on the Practitioner resource, it must be valid (exactly 10 digits). The bot will throw an error if an invalid NPI is provided.

Example of a Practitioner resource with all required fields
{
"resourceType": "Practitioner",
"id": "practitioner-123",
"name": [
{
"prefix": ["Dr."],
"given": ["John"],
"family": "Doe"
}
],
"birthDate": "1975-05-15",
"identifier": [
{
"system": "http://hl7.org/fhir/sid/us-npi",
"value": "1234567893" // Required: exactly 10 digits
}
],
"telecom": [
{
"system": "email",
"value": "john.doe@example.com"
},
{
"system": "phone",
"use": "work",
"value": "555-123-4567"
}
],
"address": [
{
"line": ["123 Main St", "Suite 100"], // At least one line required
"city": "San Francisco",
"state": "CA",
"postalCode": "94102"
}
],
"active": true
}

Usage​

Basic Example​

const DOSESPOT_ENROLL_PRESCRIBER_BOT: Identifier = {
system: 'https://www.medplum.com/bots',
value: 'dosespot-enroll-prescriber-bot',
};

const result = await medplum.execute(DOSESPOT_ENROLL_PRESCRIBER_BOT, {
practitionerId: 'practitioner-123',
practitionerRoleTypes: [1], // PrescribingClinician
}) as {
doseSpotClinicianId: number;
projectMembership: ProjectMembership;
};

Response Interface​

interface DoseSpotEnrollPrescriberResponse {
doseSpotClinicianId: number; // The DoseSpot clinician ID assigned to the prescriber
projectMembership: ProjectMembership; // Updated ProjectMembership with DoseSpot identifier
}

Available Clinician Role Types​

The DoseSpotClinicianRoleType enum includes the following values:

ValueEnum NameDescription
1PrescribingClinicianPrescriber who can write prescriptions
2ReportingClinicianClinician who can report
3EpcsCoordinatorEPCS coordinator
4ClinicianAdminClinic administrator
5PrescribingAgentClinicianPrescribing agent
6ProxyClinicianProxy clinician

Important Notes​

  • The bot will throw an error if the Practitioner does not have a ProjectMembership
  • The bot will throw an error if the ProjectMembership already has a DoseSpot identifier
  • The Practitioner's NPI must be valid (10 digits) and will be validated
  • DEA numbers must match the format: ^[A-Za-z]{2}[0-9]{7}$ or similar patterns
  • Medical license numbers can be 0-35 characters
  • After successful enrollment, the DoseSpot clinician ID will be added to the ProjectMembership's identifier array with the system https://dosespot.com/clinician-identifier

Processing DoseSpot Notifications​

You can use the useDoseSpotNotifications hook to poll for DoseSpot notifications.

See an example implementation in the Provider App's DoseSpotIcon.

Practitioner AccessPolicy​

The following AccessPolicy can be used to ensure that practitioners have the correct permissions to view and interact with DoseSpot resources in Medplum.

{
"resourceType": "AccessPolicy",
"name": "Dosespot Practitioner Example Access Policy",
"resource": [
{
"resourceType": "Patient",
},
{
"resourceType": "MedicationRequest"
},
{
"resourceType": "AllergyIntolerance"
},
{
"resourceType": "Consent"
},
{
"resourceType": "ProjectMembership",
"readonly": true
},
{
"resourceType": "MedicationKnowledge",
"readonly": true
}
//...
]
}