API Programs > Pharmacy Prescription API

Pharmacy Prescription API


The Walgreens Pharmacy Prescription API allows users of third-party applications to quickly order refills of prescriptions originally filled at one of the 8,200+ Walgreens pharmacies. Your app users can order refills in seconds, as well transfer non-Walgreens prescriptions to their nearest Walgreens to be notified when their prescription order is ready for pick up. The health care focused Pharmacy Prescription API is designed to increase prescription compliance and aid in personal health management through automated refill alerts and a streamlining of the refill process. By offering easy prescription refills through this health management API, Walgreens hopes to further increase health care adherence by reaching a wider audience through third party health care apps.

Version Highlights /v1:

  • Massive Update: The APIs are now restful and can be integrated into any web server or mobile platform!

Below are the technical steps you will need to go through in order to get your integration configured and branded correctly:


The following API endpoints can be used to programmatically integrate all functions of the RX Refill or Transfer API:

Refill

  • Obtain:
    POST /api/util/mweb5url
  • Open:
    POST {LANDING_URL}
  • Callback:
    POST {CALLBACK_URL}

Transfer

  • Obtain:
    POST /api/util/mweb5url
  • Open:
    POST {LANDING_URL}
  • Callback:
    POST {CALLBACK_URL}

Obtain Refill

This service is used to fetch the "landingURL" used for the Rx Refill API.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/util/mweb5url
Production:
https://services.walgreens.com/api/util/mweb5url

Endpoint Information

Request format JSON
Response format JSON
Authentication? Yes
Rate limited? Yes
Requests Per Minute 300

Request Body

Name Optionality Description Example
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
transaction required The Transaction is a value that invokes the refill service. The value must be "refillByScan". "refillByScan"
act required The Action is a value that invokes our internal service. "mweb5Url"
view required The View is a value that invokes our internal service. "mweb5UrlJSON"
appVer optional The build version of your application. "1.0"
devInf optional The device manufacturer and version. "iPhone,13.0"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/util/mweb5url \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"transaction":"refillByScan", \ 
	"act":"mweb5Url", \
	"view":"mweb5UrlJSON", \
	"devInf":"DEVICE,##.#" \
	"appVer":"#.#", \
}' \
						

Example Response

{
    "landingUrl": "CHECKOUT LANDING URL",
    "template": "TEMPLATE FOR CUSTOM TEMPLATES",
    "token": "ACCESS TOKEN FOR CHECKOUT",
    "err": "ERROR CODE NUMBER"
}
						

Open Refill

This service is used to open the "landingURL" used for the Rx Refill API.

Endpoint URL

Sandbox:
[landingURL]
Production:
[landingURL]

Endpoint Information

Request format JSON
Response format JSON
Authentication? Yes
Rate limited? Yes
Requests Per Minute 300

Request Body

Name Optionality Description Example
affId required Your AffiliateID. "AAAAAAAAAA"
token required The Token is a value that associates the checkout to the landingURL. The value must be re-obtained for every checkout. "token"
lat optional The Latitude coordinate of the user. "42.138199"
lng optional The Longitude coordinate of the user. "-87.945799"
rxNo required The rxNo is the number either scanned/manually entered by the customer. Sample Prescription Numbers
trackingId optional The trackingId is a value that can be used for tracking orders on your system. "AAAAA"
appID required The appId is a value that invokes our internal service. "refillByScan"
act required The Action is a value that invokes our internal service. "chkExpRx"
appVer optional The build version of your application. "1.0"
devInf optional The device manufacturer and version. "iPhone,13.0"

Example Request

curl --location --request POST '{{RX_LANDING_URL}}' \
	--form '"affId"=rxapi' \
	--form '"token"={{RX_TOKEN}}' \
	--form '"lat"=35.9218452' \
	--form '"lng"=-86.7942764' \
	--form '"rxNo"=0459772-59382' \
	--form '"appCallBackScheme"=http://localhost:3000/callback' \
	--form '"appCallBackAction"=refill' \
	--form '"trackingId"=123456789' \
	--form '"appId"=refillByScan' \
	--form '"act"=chkExpRx' \
	--form '"devinf"=Postman,1.0' \
	--form '"appver"=1.0'\
						
						

Example Response

{
"The HTML markup for the checkout of the Rx Refill API, that should be loaded into a WebView"
}
					

Handling Refill Callbacks:

Once the user has loaded the checkout page there are some user engagements that must be handled by your callback URL passed in generating the checkout:

Possible Refill Callback Scenarios:

  • When the user taps the "Cancel" button on the landing page
  • When the user taps the "Back" button on the landing page
  • When the user taps the "Close" button on the prescription confirmation page
  • When the user taps the "Refill Another" button on the prescription confirmation page
  • After an invalid prescription number alert


Example of a call from the "Refill Another" button being pressed: "appCallbackScheme://appCallbackScheme?appCallbackAction=fillAnother"

func application(_ app: UIApplication, open url: URL, options: 
	[UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
let arrURL:Array = url.absoluteString.components(separatedBy: "?")
let arrQuery:Array = arrURL[1].components(separatedBy: "=")
if(url.scheme == "refiller" && arrQuery[0] == "action")
{
	switch (arrQuery[1])
	{
		case "refillTryAgain":
		//Open the Error View Controller, they entered an invalid Rx Number
		case "cancel":
		//Open the Error View Controller, customer chose to cancel their refill
		case "back":
		//Open the Error View Controller, customer chose to back out of the refill
		case "close":
		//Open the Success View Controller, their Rx is on its way
		case "fillAnother":
		//Open the Refill View Controller, they want to refill another Rx
		default:
		//Open the Error View Controller, something bad happened during checkout
	}
	return true
}
else {return false}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
	Uri appCallbackURI = Uri.parse(url);
	if (appCallbackURI != null && appCallbackURI.getScheme().equalsIgnoreCase("refiller"))
	{
		String action = appCallbackURI.getQueryParameter("action");
		switch(action)
		{
			case action.equalsIgnoreCase("refillTryAgain"):
				//Open the Error Activity, they entered an invalid Rx Number
			case action.equalsIgnoreCase("cancel"):
				//Open the Error Activity, customer chose to cancel their refill
			case action.equalsIgnoreCase("back"):
				//Open the Error Activity, customer chose to back out their refill
			case action.equalsIgnoreCase("close"):
				//Open the Success Activity, their Rx is on its way
			case action.equalsIgnoreCase("fillAnother"):
				//Open the Refill Activity, they want to refill another Rx
			default:
				//Open the Error Activity, something bad happened during checkout
		}
	}
}

@Override
public void onBackPressed()
{
	if (webview.getVisibility() == View.VISIBLE)
	{
		if (webview.canGoBack())
		{
			//Java script call to dismiss the Native calendar Control
			webview.loadUrl("javascript:dismissCalendar();");
			//Java script call to handle page navigations
			webview.loadUrl("javascript:nativeBackBtnClicked();");
		}
		else 
		{
			Intent intent = new Intent(CustomWebView.this, MainActivity.class);
			CustomWebView.this.startActivity(intent);
			finish();
		}
	}
}
}
//Route in your app.js file, for the callback action we passed of "rx", the query string value 
will be the value you passed when creating the checkout for 
"appCallbackAction" app.get('/callback',function(req,res)

{	
	var rx = (req.query.rx) ? req.query.rx : "";
	
	res.render("pages/callback",{title:rx,rx:rx});
});

//We use then use EJS to render content for the appropriate callback action value on callback.ejs 
page (you can use any view rendering engine)

switch (rx) {
	case 'refillTryAgain' :
    	Warning! Invalid Rx Number.
		Try Again?
    break;
	case 'cancel' :
    	Warning! You have cancelled the refill.
    	Try Again?
    break;
	case 'back' : 
		Warning! You have backed out of the refill.
        Try Again?
    break;
	case 'close' : 
		Success! The pharmacist has begun to process your refill.
		Want a status Update?
    break;
	case 'fillAnother' :
    	//Send them to refill homepage to refill another
    break;
}
}

Obtain Transfer

This service is used to fetch the "landingURL" used for the Rx Transfer API.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/util/mweb5url
Production:
https://services.walgreens.com/api/util/mweb5url

Endpoint Information

Request format JSON
Response format JSON
Authentication? Yes
Rate limited? Yes
Requests Per Minute 300

Request Body

Name Optionality Description Example
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
transaction required The Transaction is a value that invokes the refill service. "refillByScan"
act required The Action is a value that invokes our internal service. "mweb5Url"
view required The View is a value that invokes our internal service. "mweb5UrlJSON"
appVer optional The build version of your application. "1.0"
devInf optional The device manufacturer and version. "iPhone,13.0"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/util/mweb5url \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"transaction":"refillByScan", \ 
	"act":"mweb5Url", \
	"view":"mweb5UrlJSON", \
	"devInf":"DEVICE,##.#" \
	"appVer":"#.#", \
}' \
		
						

Open Transfer

This service is used to make a web request to the "landingURL" used for the Rx Transfer API.

Endpoint URL

Sandbox:
[landingURL]
Production:
[landingURL]

Endpoint Information

Request format JSON
Response format JSON
Authentication? Yes
Rate limited? Yes
Requests Per Minute 300

Request Body

Name Optionality Description Example
affId required Your AffiliateID. "AAAAAAAAAA"
token required The Token is a value that associates the checkout to the landingURL. The value must be re-obtained for every checkout. "token"
lat optional The Latitude coordinate of the user. "42.138199"
lng optional The Longitude coordinate of the user. ""-87.945799"
rxImg required The rxImg is the Base64 encoded image data as a string pulled from a picture of the customers pill bottle. "rxImg.jpg"
fname optional The customers first name. "firstName"
lname optional The customers last name. "lastName"
dob optional The customers date of birth. "MM-DD-YYYY"
phoneNbr optional The phone number of the customer. "5555555555"
pharmacyNbr optional The customers previous pharmacy phone number, usually placed on the Rx Label. "5555555555"
trackingId optional The trackingId is a value that can be used for tracking orders on your system. "AAAAA"
appID required The appId is a value that invokes our internal service. "transferByScan"
act required The Action is a value that invokes our internal service. "transferRxHome"
appVer optional The build version of your application. "1.0"
devInf optional The device manufacturer and version. "iPhone,13.0"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/util/mweb5url \
--header 'Content-Type: application/json' \
--data '{ \
	"affId":"YOUR_AFFILIATE_ID", \
	"token":"ACCESS_TOKEN", \ 
	"lat":"Latitude", \ 
	"lng":"Longitude", \ 
	"rxImg":"BASE64_ENCODED_IMAGE_DATA_STRING, \ 
	"fname":CUSTOMER_FIRST_NAME", \ 
	"lname":CUSTOMER_LAST_NAME", \ 
	"dob":CUSTOMER_DATE_OF_BIRTH", \ 
	"phoneNbr":CUSTOMER_PHONE_NUMBER", \ 
	"pharmacyNbr":CUSTOMER_OLD_PHARMACY_PHONE_NUMBER", \ 
	"trackingId":"TRACKING_ID", \ 
	"appId":"transferByScan", \ 
	"act":"transferRxHome", \ 
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#" \
}' \
						

Example Response

{
"The HTML markup for the checkout of the Rx Refill API, that should be loaded into a WebView"
}
						

Handling Transfer Callbacks:

Once the user has loaded the checkout page there are some user engagements that must be handled by your callback URL passed in generating the checkout:

Possible Transfer Callback Scenarios:

  • When the user taps the "Cancel" button on the landing page or on the transfer review page
  • When the user taps the "Back" button on the landing page
  • When the user taps the "Home" button on the transfer confirmation page
  • When the user taps the "Transfer Another" button on the transfer confirmation page
  • When the user taps the "Done" button on the transfer confirmation page



Example of a call from the "Refill Another" button being pressed: "appCallbackScheme://appCallbackScheme?appCallbackAction=fillAnother"

func application(_ app: UIApplication, open url: URL, options: 
[UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
	let arrURL:Array = url.absoluteString.components(separatedBy: "?")
	let arrQuery:Array = arrURL[1].components(separatedBy: "=")
	if(url.scheme == "transfer" && arrQuery[0] == "action")
	{
		switch (arrQuery[1])
		{
			case "txCancel":
			//Open the Error View Controller, 
			//customer chose to cancel their transfer 

			case "txHome":
			//Open the Error View Controller, 
			//customer chose to hit home on the checkout page

			case "txDone":
			//Open the Success View Controller, 
			//their transfer is on its way to the store!

			case "txAnother":
			//Open the Transfer View Controller, 
			//they want to transfer another Rx

			default:
			//Open the Error View Controller, 
			//something bad happened during checkout
		}
		return true
	}
	else {return false}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
  Uri appCallbackURI = Uri.parse(url);
  if (appCallbackURI != null 
  && appCallbackURI.getScheme().equalsIgnoreCase("transfer")){

	String action = appCallbackURI.getQueryParameter("action");
	switch(action)
	{
		case action.equalsIgnoreCase("txCancel"):
		//Open the Error View Controller, customer chose to 
		//cancel their transfer or back out of it

		case action.equalsIgnoreCase("txHome"):
		//Open the Error View Controller, customer chose to 
		//hit home on the checkout page

		case action.equalsIgnoreCase("txDone"):
		//Open the Success View Controller, their transfer 
		//is on its way to the store!

		case action.equalsIgnoreCase("txAnother"):
		//Open the Transfer View Controller, 
		//they want to transfer another Rx

		default:
		//Open the Error View Controller, 
		//something bad happened during checkout
	}
  }
}

@Override
public void onBackPressed()
{
	if (webview.getVisibility() == View.VISIBLE)
	{
		if (webview.canGoBack())
		{
			//Java script call to dismiss the Native calendar Control
			webview.loadUrl("javascript:dismissCalendar();");
			//Java script call to handle page navigations
			webview.loadUrl("javascript:nativeBackBtnClicked();");
		}
		else 
		{
			Intent intent = new Intent(CustomWebView.this, MainActivity.class);
			CustomWebView.this.startActivity(intent);
			finish();
		}
	}
}
//Route in your app.js file, for the callback action we passed of "rx", the query 
string value will be the value you passed when creating the checkout for 
"appCallbackAction" app.get('/callback',function(req,res)
{	
	var rx = (req.query.rx) ? req.query.rx : "";
	
	res.render("pages/callback",{title:rx,rx:rx});
});

//We use EJS to then render content for the appropriate callback action value 
switch (rx) {
	case 'txCancel' :
    	Warning! You have cancelled the transfer.
		Try Again?
	case 'txHome' :
    	Warning! You have backed out of the transfer.
	    Try Again?
	break;
	case 'txDone' :
    	Success! The pharmacist has begun to process your transfer.
	    Want a status Update?
	case 'txAnother' :
    	//Send them to refill homepage to refill another
    break;

Error Codes

Error Codes for Rx Refill Service

Obviously we don't want any errors to happen, but sometimes they do and as a result we respond the following error codes. The table below helps explain why each of the error codes could occur:

Code Type Message
111,112,113,114,115,116 ERROR Configuration issues found in JSON body.
117 ERROR We are unable to complete your request. Please try again later.
118 ERROR A required attribute is missing in the request.
120 ERROR The Rx Number is invalid.
121 ERROR The Rx number entered is a Medicare Part B prescription. It can be refilled by calling 888-727-8265.
122 ERROR The Rx number entered is a Mail Service prescription. It can be refilled by calling 866-525-1590.
123,124,125,126,127 ERROR The Rx number entered cannot be filled at that store. Please select a different store.
128 ERROR Network error, please try again.
1001 ERROR We are unable to enroll you in Rx Text alerts at this time. Please try again later.
1003 ERROR We are unable to complete your request. Please try again later.
202 ERROR We are unable to complete your request. Please try again later.
205 ERROR No request parameters found.
209 ERROR We are unable to locate any stores based on your current location.
ERR_DEFAULT ERROR We are unable to complete your request.
ERR_PRES_CANT_PICKED ERROR Unable to refill that prescription now. Please contact the Pharmacist.
VALIDATE_RX_WRN_MSG ERROR There are no refills left for that prescription.
ERR_TEXT_SUBSCR ERROR Unable to enroll you in Rx Text alerts. Please try again later.
ERR_NET_FAIL ERROR We are unable to complete your request. Please try again later.
ERR_APP_ID_INCORRECT ERROR We are unable to locate any stores based on your current location.
ALERT_ERR_INVALID_TIME ERROR Please select a valid store pickup time.
ALERT_NO_STORES_FOUND ERROR We are unable to locate any stores based on your current location.
ALERT_ERR_VALID_PHNO ERROR Customer entered a valid phone number.

Error Codes for Rx Transfer Service

Code Type Message
603 ERROR We are unable to complete your request. Please try again later.
630 ERROR Please enter a valid phone number.
632 ERROR Please enter all required information.
633 ERROR Please enter a valid pharmacy phone number.
635 ERROR Sorry, failed to subscribe for text messages.
636 ERROR A required attribute is missing in the request.
638 ERROR Invalid SMS OPT Service.
658 ERROR Missing device info.
111,112,113,114,115,116 ERROR Configuration issues found in JSON body.
118 ERROR A required attribute is missing in the request.
202 ERROR We are unable to complete your request. Please try again later.
205 ERROR No request parameters found.
209 ERROR We are unable to locate any stores based on your current location.
1003 ERROR We are unable to complete your request. Please try again later.
ERR_GEN_PDF ERROR We are unable to complete your request. Please try again later.
ERR_MISSING_MANDATORY_FLDS ERROR Please enter all required information.
ERR_INVALID_PH_NO ERROR Please enter a valid phone number.
ERR_INVALID_PHARMACY_PH_NO ERROR Please enter a valid pharmacy phone number.
ERR_NO_RESPONSE ERROR We are unable to complete your request. Please try again later.
ERR_DEFAULT ERROR We are unable to complete your request. Please try again later.
ALERT_NO_STORES_FOUND ERROR We are unable to locate any stores based on your current location.
ERR_APP_ID_INCORRECT ERROR Requested application not found in the configuration file.