Home - The latest
About the code boxes


Coding
AVR-GCC
BCB
jQuery
PHP
VBA
Websites

APIs
Amazon Product API
eBay APIs
eBay Partner Network EPN
eBay Daily Deals

Utilities
Serial Barcoder Wedge
NetDebug Script Monitor

Other Sites
BINSniper in jQuery

Notes to the world
An end to spam
Gold Plating

Support this site
Donations, purchases from eBay or Amazon using the links on this site, or just linking to this site on your Facebook page or website enable me to keep it running. Thanks.


Looking for info on ALS?
(Lou Gehrig's Disease)
Click Here

A drop-in function to sign Amazon requests v2

Amazon implemented a signing requirement for Product Advertising API requests in August 2009. Signing is required on calls to Amazon to retrieve API data, it is not required on the display URLs on your website. This function is designed to be a drop in for existing API code. You create your URL following the API docs and then use this function to sign it. It accepts a rawurlencoded unsigned URL, adds a timestamp, calculates and adds a signature value and returns the result. The function follows the guidelines posted on Amazon's Example REST Requests page. At the time of this writing, the Amazon page does not indicate in step 9 that slashes(/) must also be urlencoded.

Do not pass the function a URL with a timestamp, it will add the timestamp and signature for you. You must change the secret access line to your Secret Access Key from your Amazon account management screen.

function sign_url($url){
  $secret = '<YOUR SECRET ACCESS KEY HERE>';  
  $host = parse_url($url,PHP_URL_HOST);
  $timestamp = gmstrftime("%Y-%m-%dT%H:%M:%S.000Z");
  $timestamp = "&Timestamp=" . rawurlencode($timestamp);

  $paramstart = strpos($url,"?");
  $workurl = substr($url,$paramstart+1,99999);
  $workurl = str_replace(",","%2C",$workurl);
  $workurl = str_replace(":","%3A",$workurl);
  $workurl .= $timestamp;
  
  $params = explode("&",$workurl);
  sort($params);

  $signstr = "GET\n" . $host . "\n/onca/xml\n" . implode("&",$params);
  $signstr = base64_encode(hash_hmac('sha256', $signstr, $secret, true));
  $signstr = rawurlencode($signstr);
  $signedurl = $url . $timestamp . "&Signature=" . $signstr;
  return $signedurl;
}

// call the function in one of the following ways:
echo sign_url($url) . "<BR>";
$signedurl = sign_url($unsignedurl);
At present, there doesn't seem to be any simple signed URL validator available from Amazon. You can validate by comparing your URLs to Amazon generated ones, by following these steps:

A note about the use of base64 within the function.
A few people have commented that the function should use rawurlencode() instead of urlencode() when generating the signature. Base64 data cannot contain spaces, so either function will work. If switched it to rawurlencode() to put an end to the questions.

Updated: 2 June 2009 - time set to GMT
Updated: 3 June 2009 - dropped optional 3rd param on substr()
Updated: 23 July 2010 - rawurlencoded the timestamp output and added note that rawurlencode is required on the input URL


Article ID: api_signing_amazon_api_requests



Books from Amazon: