API Programs > Native Photo Prints API

Native Photo Prints API


The Native Photo Prints API enables third party integrations to upload photos, fetch product details, validate coupons, search for stores, and finally submit orders for same-day printing of photo orders at any one of our thousands of Walgreens Stores. Once an order has been submitted its order status can be fetched.

Version Highlights /v3:

  • New Upload Process, image files no longer accessible once uploaded!
  • New Fetch Status endpoint for realtime Order Status information!
  • New Documentation Design, let us know what you think!

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 Native Photo Prints API experience:

Upload

  • Fetch Credentials:
    POST /api/util/v3.0/mweb5url
  • Generate Token:
    {IN_YOUR_CODE}
  • Upload Images:
    PUT {UPLOAD_URL}

Products

  • Details:
    POST /api/photo/products/v3

Coupons

  • Validate:
    POST /api/photo/order/coupon/v3

Stores

  • Search:
    POST /api/photo/store/v3

Orders

  • Submit:
    POST /api/photo/order/submit/v3
  • Status:
    POST /api/photo/order/status/v3

Fetch Upload Credentials

This endpoint can be used to fetch the credentials needed to upload images to the Walgreens Storage server. Take note, when uploading to our storage, the files will not be accessible once uploaded and you should save image data if planning to use later in your checkout flow for previewing the images.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/creds/v3
Production:
https://services.walgreens.com/api/photo/creds/v3

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"
platform required The software platform. "ios" || "android"
transaction required A static value describing the reason for fetching the credentials. "photocheckoutv2"
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/photo/creds/v3 \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"platform":"ios", \
	"transaction":"photocheckoutv2", \ 
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#" \
}' \
						

Example Response

{
	"uploadLimit": 200,
	"template": "default",
	"landingUrl": "https://m5.walgreens.com/photoprints/",
	"cloud": [{
		"sasKeyToken": "https://pstrgqp01.blob.core.windows.net/qpcontainerin?sig=BLAHBLAHBLAH&se=YYYY-MM-DDT22%3A53%3A57Z&sv=YYYY-MM-DD&sp=w&sr=c"
	}]
}
						

Generate Upload Token

Before an image can be uploaded, the value for the sasKeyToken (looks like a url) must be converted correctly into the Upload_URL. This is completed by doing the following:

Step by Step Guide

  • A) Split the "sasKeyToken" value on the "?" character into a string array
  • B) Create a string from the first element of the string array lets call it blobContainer
  • C) Create a string from the second element of the string array lets call it signature
  • D) Create a string of the imageName, example:
    "Image-"+YOUR_AFFILIATE_ID+"-"+generateUUID()+".jpg" lets call it imageName
  • E) Generate the Upload_URL like so: blobContainer+"/"+imageName+"?"+signature

Example Code

SWIFT:
let blobContainer:String = sasToken.components(separatedBy: "?").first!
let signature:String = sasToken.components(separatedBy: "?").last!
let imageName:String = "Image-\(affId)-\(UUID().uuidString).jpg"
let Upload_URL:String = "\(blobContainer)/\(imageName)?\(signature)"

KOTLIN:
var blobContainer:String = sasToken.split("?").toTypedArray().first()
var signature:String = sasToken.split("?").toTypedArray().last()
var imageName:String = "Image-".plus(affId).plus("-").plus(UUID.randomUUID().toString()).plus(".jpg")
var Upload_URL:String = blobContainer.plus("/").plus(imageName).plus("?").plus(signature)

JAVASCRIPT:
function generateUUID() 
{
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c)
  {
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}
var blobContainer = sasToken.split("?").shift();
var signature = sasToken.split("?").pop();
var imageName = "Image-"+affId+"-"+generateUUID()+".jpg";
var Upload_URL = blobContainer+"/"+imageName+"?"+signature;
						

Example Output

https://pstrgqp01.blob.core.windows.net/qpcontainerin/Image-YOUR_AFFILIATE_ID-a12b3cd-e4f5-6789-ghi0-1234567j89kl.jpg?sig=BLAHBLAHBLAH&se=YYYY-MM-DDT22%3A53%3A57Z&sv=YYYY-MM-DD&sp=w&sr=c
						

Upload Images

To upload an image, make a PUT request to the generated UPLOAD_URL with the custom HTTP headers. Place the image data to be uploaded in the HTTP body. If multiple images are to be printed, repeat the process above for every single image.

Endpoint URL

The image url is generated using the process above.

Endpoint Information

Request format Binary Data
Response format XML
Authentication? Yes
Rate limited? No

Request Headers

Name Optionality Description Example
Content-Type required The type of image format for the file. We convert the file to JPEG on our side, however we prefer you do this on your side. image/jpeg
Content-Length required The count of the bytes of data in the image file. 1073741824
x-ms-client-request-id required A Universally Unique Identifier (UUID) for each request. a12b3cd-e4f5-6789-ghi0-1234567
x-ms-blob-type required A static value describing the request upload type. BlockBlob

Request Body

The binary data of the image file.

Example Request

curl -X PUT \
'https://pstrgqp01.blob.core.windows.net/qpcontainerin/Image-YOUR_AFFILIATE_ID-a12b3cd-e4f5-6789-ghi0-1234567j89kl.jpg?sig=BLAHBLAHBLAH&se=YYYY-MM-DDT22%3A53%3A57Z&sv=YYYY-MM-DD&sp=w&sr=c' \
-H 'Content-Length: 1073741824' \
-H 'Content-Type: image/jpeg' \
-H 'x-ms-blob-type: BlockBlob' \
-H 'x-ms-client-request-id: a12b3cd-e4f5-6789-ghi0-1234567' --upload-file image.jpeg
						

Example Response

HTTP STATUS CODE: 201

Custom Upload Images

You are absolutely able to use your own url for images uploaded to another server then the Walgreens server. Please ensure the url is accessible for at least 36 hours (due to delays at store level) with a simple HTTP Get Request and that as that is how our image downloader will get the file to the store.


Product Details

Used to get the list of photo products & price details that have been configured for your application. You should call this every single time you are showing products or prices in your UI to the customer. Prices and Products are subject to change at anytime.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/products/v3
Production:
https://services.walgreens.com/api/photo/products/v3

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"
productGroupId optional Used to differentiate product groups for filtering the product list results. "STDPR" || "SQR01"
act required A static value that tells our service what action the request is making. "getphotoprods"
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/photo/products/v3 \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"productGroupId":"STDPR", \
	"act":"getphotoprods", \
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#" \
}' \
						

Example Response

{
    "errDesc": "",
    "err": "",
    "products": [{
        "productId": "The Product Id",
        "boxQty": "The number of times the image is printed for this product",
        "productSize": "4x6",
        "productGroupId": "STDPR",
        "offsetWidth": "Offset width from edge of image for product",
        "woodFrameColor": "Wood Frame Color (Floating Frames only)",
        "templateUrl": "A template url (Creative Products only)",
        "productDesc": "4x6 Internet Print",
        "portraitTemplateUrl": "A portrait template url (Creative Products only)",
        "resWidth": "Resolution width (Creative products only)",
        "offsetHeight": "Offset height from edge of image for product",
        "vendorQtyLimit": "Limit of Product per Order (Creative Products only)",
        "backerBoardColor": "Board Back Color (Floating Frames only)",
        "dpi": "Dots Per Inch (Creative products only)",
        "multiImageIndicator": "Y || N (Creative products only)",
        "resHeight": "Resolution height (Creative products only)",
        "productPrice": "The price of the product, ex 0.01"
    },
	...shortened for brevity
	]
}
						

Validate Coupon

Used to validate a coupon code & retrieve offer details and the updated price. The couponCode should only be added to the submit order request body if it has been successfully validated with this endpoint.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/order/coupon/v3
Production:
https://services.walgreens.com/api/photo/order/coupon/v3

Endpoint Information

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

Warnings

Request Body

Name Optionality Description Example
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
couponCode required The actual coupon code being applied to the order. "TESTFORALL"
act required A static value that tells our service what action the request is making. "getdiscount"
appVer required The build version of your application. "1.0"
devInf required The device manufacturer and version. "iPhone,13.0"
productDetails required An array of JSON Product objects. JSON Product objects will contain the two below parameters. [{"productId":"0000001", "qty":"10"}, {"productId":"0000002", "qty":"1"}]
productId required The Product Id obtained from the service above which the user has selected to add to the cart. "0000001"
qty required This is the quantity of the product that the customer has selected to add to the cart. "10"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/photo/order/coupon/v3 \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"couponCode":"TESTFORALL", \
	"act":"getdiscount", \
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#", \
	"productDetails":[{ \
		"productId":"0000001", \
		"qty":"10" \
	}], \
}' \
						

Example Response

{
    "errDesc": "",
    "err": "",
    "orderTotalPrice": 40.00,
    "orderDiscountPrice": 8.00,
    "status": "success"
}
						

Store Search

Used to retrieve list of available & applicable photo printing stores near customer. This endpoint takes into account the stores that are currently available to print an order based on the cart that that the user has built.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/store/v3
Production:
https://services.walgreens.com/api/photo/store/v3

Endpoint Information

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

Warnings

Request Body

Name Optionality Description Example
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
latitude required The actual latitude of the customer. "41.880977"
longitude required The actual longitude of the customer. "-87.626481"
act required A static value that tells our service what action the request is making. "photoStores"
appVer required The build version of your application. "1.0"
devInf required The device manufacturer and version. "iPhone,13.0"
productDetails required An array of JSON Product objects. JSON Product objects will contain the two below parameters. [{"productId":"0000001", "qty":"10"}, {"productId":"0000002", "qty":"1"}]
productId required The Product Id obtained from the service above which the user has selected to add to the cart. "0000001"
qty required This is the quantity of the product that the customer has selected to add to the cart. "10"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/photo/store/v3 \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"latitude":"41.880977", \
	"longitude":"-87.626481", \
	"act":"photoStores", \
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#", \
	"productDetails":[{ \
		"productId":"0000001", \
		"qty":"10" \
	}], \
}' \
						

Example Response

{
  "status": "success",
  "errCode": "",
  "errDesc": "",
  "photoStores": [{
    "photoStoreDetails": {
      "storeNum": "STORE NUMBER",
      "promiseTime": "STORE PROMISE TIME",
      "type": "STORE TYPE WAG/DR",
      "zip": "STORE ZIP CODE",
      "city": "STORE CITY",
      "state": "STORE STATE",
      "street": "STORE STREET",
      "county": "STORE COUNTY",
      "latitude": "STORE LATITUDE",
      "longitude": "STORE LONGITUDE",
      "phone": "STORE PHONE NUMBER",
      "distance": "USER DISTANCE FROM STORE",
      "distanceUnit": "DISTANCE UNIT OF MEASUREMENT",
      "openTime": "STORE OPEN TIME",
      "closeTime": "STORE CLOSE TIME",
      "extendedHours": "STORE HAS EXTENDED HOURS",
      "storeName": "STORE NAME",
      "holidayEventName": "HOLIDAY EVENT NAME",
      "timeZone": "STORE TIME ZONE",
      "tax": "STORE TAX PERCENTAGE"
    }
  },
  ...shortened for brevity
  ]
}
						

Order Submit

This endpoint can be used to submit the order containing the selected products, applicable coupon code, and selected store.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/order/submit/v3
Production:
https://services.walgreens.com/api/photo/order/submit/v3

Endpoint Information

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

Warnings

Request Body

Name Optionality Description Example
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
publisherId optional Your Publisher Id, Learn more here: https://developer.walgreens.com/support/revenue-share. "12345678"
firstName required The First Name of the customer. A required input from the user. "John"
lastName required The Last Name of the customer. A required input from the user. "Smith"
phone required The Phone Number of the customer. A required input from the user. "8009254733"
email required The Email of the customer. A required input from the user. "apibizdev@walgreens.com"
couponCode optional If the couponCode has been validated for the cart, pass the couponCode here. "TESTFORALL"
storeNum required The store number selected by the customer returned from the Store Search endpoint. "211"
promiseTime required The promise time of the store selected by the customer returned from the Store Search endpoint, must be fetched uniquely for every order. "MM-DD-YYYY H:MM AM/PM"
affNotes optional The notes to the printer, if needed. Can also be used to pass a unique tracking ID from your side that we can reference later for reporting. "12345678" || "Don't put a backing on the frame"
act required A static value that tells our service what action the request is making. "submitphotoorder"
appVer required The build version of your application. "1.0"
devInf required The device manufacturer and version. "iPhone,13.0"
productDetails required An array of JSON ProductDetails objects. JSON ProductDetails objects will contain the two below parameters. [{ "productId":"0000001", "imageDetails":SEE BELOW }, { "productId":"0000002", "imageDetails":SEE BELOW }, ...Repeated for every unique productId ]
productId required The Product Id obtained from the service above which the user has selected to add to the cart. "0000001"
imageDetails required An array of JSON imageDetails objects. JSON imageDetails objects will contain the two below parameters. [{ "qty":"1", "url":"UPLOAD_URL" }, ...Repeated for each image for a productId ]
url required This is the url where the image is uploaded. "UPLOAD_URL"
qty required This is the quantity of the product that the customer has selected to add to the cart. "10"

Example Request

curl --request POST \ 
--url https://services-qa.walgreens.com/api/photo/order/submit/v3 \
--header 'Content-Type: application/json' \
--data '{ \
  "apiKey":"YOUR_API_KEY", \
  "affId":"YOUR_AFFILIATE_ID", \
  "publisherId": "YOUR PUBLISHER ID", \
  "firstName": "CUSTOMER FIRST NAME", \
  "lastName": "CUSTOMER LAST NAME", \
  "phone": "CUSTOMER PHONE NUMBER", \
  "email": "CUSTOMER EMAIL ADDRESS", \
  "storeNum": "STORE NUMBER SELECTED", \
  "promiseTime": "PROMISE TIME FOR SELECTED STORE", \
  "affNotes": "TRACKING ID FOR YOUR LOGS", \
  "act": "submitphotoorder", \
  "appVer":"#.#", \
  "devInf":"DEVICE,##.#" \
  "productDetails": [{ \
    "productId": "PRODUCT ID", \
    "imageDetails":[{ \
      "qty": "IMAGE URL QUANTITY", \
      "url": "IMAGE URL" \
    },{
      "qty": "IMAGE URL QUANTITY", \
      "url": "IMAGE URL" \
    }] \
  },{ \
    "productId": "PRODUCT ID", \
    "imageDetails":[{ \
      "qty": "IMAGE URL QUANTITY", \
      "url": "IMAGE URL" \
    }] \
  }] \
}' \
						

Example Response

{
    "vendorOrderId": "0000000001",
    "err": "",
    "errDesc": "",
    "status": "success"
}
						

Multi-Product Type

Used to submit multiple products with multiple quantities. It will collect all the necessary information required for the request to submit multiple products.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/order/submit/v3
Production:
https://services.walgreens.com/api/photo/order/submit/v3

Endpoint Information

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

Request Body

Name Optionality Description Example
firstName required First lame of the customer "firstName"
lastName required Last name of the customer "lastName"
phone required Phone number "##########"
email required The email value is the email address of the customer. "email@domain.tld"
storeNum required The store number selected by the customer returned from the Store Search endpoint. "211"
promiseTime required The promise time of the store selected by the customer returned from the Store Search endpoint, must be fetched uniquely for every order. "MM-DD-YYYY H:MM AM/PM"
currencyType required The type of currency that is used "1"
productDetails required An array of JSON ProductDetails objects. JSON ProductDetails objects will contain the two below parameters. [{ "productId":"0000001", "imageDetails":SEE BELOW }, { "productId":"0000002", "imageDetails":SEE BELOW }, ...Repeated for every unique productId ]
sdkVer required The version of the sdk "1.0.0"
apiKey required Your API Key. "AbCdEfGhIjKlMnOpQrStUvWxYz"
affId required Your AffiliateID. "AAAAAAAAAA"
act required A static value telling our service what to do, always set to the value "storenumber". "storenumber"
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/photo/order/submit/v3 \
--header 'Content-Type: application/json' \
--data '{ \
        "firstName":"OneFoldedCard",
        "lastName":"foldedcard",
        "phone":"5555555555",
        "email":"email@email.com",
        "storeNum":"59181",
        "promiseTime":"03-02-2020 5:15 PM",
        "currencyType":"1",
        "productDetails": [{
                "multiImageQuantity": "10", // Order quantity is counted based on this value
                "productId": "8420005",
                "imageDetails": [{
                    "url": "https://www.walgreens.com/livestyleguide/walgreens.com/v3.0/
                            themes/images/global/logo-corner-red.png",
                    "qty": "1"
                }, {
                    "url": "http://clipart-library.com/images/rTjraz5yc.jpg",
                    "qty": "1"
                }]
            }],
        "sdkVer":"3.4.5",
        "devinf":"DEVICE,##.#",
        "appver":"1.0",
        "act":"submitphotoorder",
        "affId":"YOUR_API_KEY",
        "apikey":"YOUR_API_KEY"
        
        } 
        
        // multiImageQuantity parameter is optional value for non creative print products    
        
        
                        

Order Status

This endpoint can be used to report on the status of orders based on an array of vendorOrderId. At least one valid vendorOrderId is needed to get back a valid status.

Endpoint URL

Sandbox:
https://services-qa.walgreens.com/api/photo/order/status/v3
Production:
https://services.walgreens.com/api/photo/order/status/v3

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"
orders required An array of vendor order Id's. ["0000000001"]
act required A static value that tells our service what action the request is making. "orderstatus"
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/photo/order/status/v3 \
--header 'Content-Type: application/json' \
--data '{ \
	"apiKey":"YOUR_API_KEY", \
	"affId":"YOUR_AFFILIATE_ID", \
	"orders": ["0000000001","0000000002","0000000003"], \
	"act": "orderstatus", \
	"appVer":"#.#", \
	"devInf":"DEVICE,##.#" \
}' \
						

Example Response

{
    "errDesc": "",
    "err": "",
    "statuses": [{
        "valid": "true",
        "code": "0",
        "orderId": "0000000001",
        "orderStatus": "Submitting"
    },
    {
        "valid": "true",
        "code": "1",
        "orderId": "0000000002",
        "orderStatus": "Downloading"
    },
    {
        "valid": "false",
        "code": "",
        "orderId": "0000000003",
        "orderStatus": ""
    }]
}
						

Possible codes:

  • 0 = "Submitting"
  • 1 = "Downloading"
  • 2 = "Printed"
  • 3 = "Ready for Pickup"
  • 4 = "Sold"
  • 5 = "Cancelled by service"
  • 6 = "Cancelled at store"


Disclaimer: Consistent with the Terms of Use, your ability to launch a production integration of an Application is subject to approval by Walgreens.