Amazon simple Api for PHP
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10 KiB

Amazons Product Advertising API for PHP

This document will describe some basics about the API. A detailed API reference for the classes shipping along can be found in the doc/apiref subdirectory.

PHP Files

  • awsv4.class.php:
    This is the "foundation", responsible to send our requests to AWS in the required format. You won't have to deal with this directly, so it will not be detailed. This class comes directly from Amazon (so it's not my work).
  • class.simplecache.php and amazon_simple_ads_class.php:
    Now, that's my work. It uses the AWSv4 class for generating the signed requests. All other logic is concentrated here. The cache class helps speeding up things (keeping once retrieved results for the 24h allowed by Amazon), and also enables us to use multiple SearchIndexes for "merged results" (only on subsequent calls, though, due to the API throtteling done by Amazon: in the past, they permitted 40 reqs/s, now it's just 1 req/s).


Simply put all the *.php files into the very same directory. You might wish to chose one that's in your PHP include path, for easier access.

Next, it's recommended to adjust the cache path in amazon_simple_ads_class.php and class.simplecache.php to point to a place where your web server has read/write access to. That's where search results returned from Amazon are temporarily stored for 24h. If the same search is issued after that, the cache file is replaced. If not, the file will stay forever; so if you're generating your queries dynamically, you might wish to set up a Cron job to take care for older files.

Moreover, if you want to offer your visitors some more privacy and not have the images served by Amazon servers, create a corresponding sub directory right inside the cache directory (default name is expected to be asap; if you want something different, see the setImgBase method's second parameter). This must be writeable by the web server process – and needs to be accessible from the DOCUMENT_ROOT (either use an alias for that, or play with symlinks).


Class initialization

Having retrieved your credentials from AWS, you somehow need to tell the class to use those. In order to not having to do this on each call, they are stored into class variables on initialization. So in your PHP code, you need to start with something similar to the following lines, while replacing the fake-credentials with your real ones:

$amazon = new AmazonAds('public_key', 'private_key', 'associate_id', 'com');
$amazon->setImgBase('/shared/images/asap'); // optional for more privacy; see „Installation“ above)

As written, use your AWS public and private keys here, plus the Amazon PartnerNet ID (looks like 'foobar-21' (Europe) or 'foobar-20' (US). Parameter #4 is optional and defines the site you intend to link to.

Querying data

Here we have mainly two approaches:

  • we know the ASIN of a product (or multiple) we want to get details on
  • we just want to search for some products matching certain criteria

The first is easy: we know exactly how many records to expect, and rawly what data they might contain. We know the product type, etc.pp. So no much fuzz – this is done and explained easily:

// a comma-separated list is allowed; and yes, these are books (ASIN=ISBN-10)
$asin = '3645603115,3645602151';
$res = $amazon->getItemByAsin($asin);

The second is a little more tricky. We need to know e.g.

  • search terms to look for
  • where to look for them (the complete catalog often is too much)

So let's take a simple example first, and search for 5 books on PHP programming:

$keywords = 'PHP Programming';
$catalog  = 'Books';
$limit    = 5;
$res2 = $amazon->getItemsByKeyword($keywords,$prodgroup,$limit);

This will give us max 5 books on PHP programming (hopefully; and the limit cannot exceed 10). Still easy, and still in the bounds of what the official API describes. So let's go a step further, and look for books on either PHP or Ruby programming, with a single call:

$keywords = 'PHP Ruby +Programming';
$catalog  = 'Books';
$limit    = 5;
$res2 = $amazon->getItemsByKeyword($keywords,$prodgroup,$limit);

Note the leading "+" sign for Programming? That means as much as "do multiple searches all with this keyword, combining it with each of the others. ASAP then takes care to

  • run multiple searches, here:
    • one for "PHP Programming"
    • one for "Ruby Programming"
    • both on the "Books" index
  • merge the results, sort out duplicates
  • return random 5 articles from the results

Pretty neat, isn't it? Except there's one caveat: Amazon decided to throttle our requests. Officially, 1 req/s is the limit – so the second lookup will fail (to my experience, even if delayed by 2+ seconds). With PA API 4 this was 40 reqs/s and thus worked straight – now you will get the "merged results" only on a second call done later (between several seconds and 24h later), when the cache already has the first part.

Now, what happens if we search for 'PHP Ruby +Advanced +Programming'? Much the same, but again only 2 searches: "PHP Advanced Programming" and "Ruby Advanced Programming". So multiple words prefixed by a "+" will "stick together".

Not enough? Yeah, what about Video Tutorials?

$keywords = 'PHP Ruby +Programming';
$catalog  = 'Books,MoviesAndTV';
$limit    = 5;
$res2 = $amazon->getItemsByKeyword($keywords,$prodgroup,$limit);

Now, that's something, right? It would do the same as the previous example, then repeat the same on the "MoviesAndTV" index (i.e. for DVDs and Bluerays), merge everything, remove dupes, return 5 items (note that dupe-check and limiting the result set will always be the last steps only, so we have a maximum pool to chose from). Unfortunately, the API limit will kick in again, so full results will only be available with the 4th call.

Evaluating results I have to admit, I somehow minimized things a little.

We're talking about placing some little ads on our site – not about presenting a full-fledged catalog. So there aren't that many details returned by ASAP. It's an array[0..$limit] of arrays with the keys:

  • title: title of the item, obviously
  • price: formatted, with currency, e.g. "EUR 20,00"
  • img: URL to the small (75px high) product image
  • url: where to send our visitors to (includes our partner tag and all)

I simply tried to stick to fields available to all Amazon products, and have the basic data required for ads available. If there's demand, the ASIN could be easily added – and then be used to query the full set of data via a method yet-to-be-implemented.


When things go wrong you might wish to know why. But errors better not show up on your website. For that, Asap uses PHP's Error Reporting, throwing E_USER_NOTICEs. You might have configured your test system to also place them on-screen – but on the production system, only to log them to the web server's error log (this is the recommended setup).

So what do the errors mean, and what guidance does Asap offer you?

Local errors

These should be pretty self-explaining:

  • The specified cache directory does not exist! Switching off local image mode.
    ⇒ you've specified a cache directory that does not exist (or cannot be accessed by the process Asap is running in).
    Solution: Check the path and its permissions. Create the path if it does not yet exist (or alter your path setting accordingly), fix permissions so Asap can read from it and write to it.
  • Warning: could not delete cache file…
    ⇒ The mentioned cache file could not be removed. Either it didn't exist anymore (no actions needed then) – or it might have the wrong permissions (e.g. it was created when testing from the command line, and now should be deleted by the web server).
    Solution: Just check: if it's there, delete it – else ignore it.
  • Warning: directory for '${fname}' does not exist or no permission to write the file, no cache written.
    Well, does this need an explanation? Hint: similar to the previous bullet point.
  • The specified language pref '$lang' is invalid, must follow the pattern 'xx_XX' or be empty.
    ⇒ valid language codes follow the pattern of a lower-case language (e.g. de or en), followed by an underscore, and then by an upper-case language variant. You've obviously used something different.
    As I didn't check all country-specific documentation, I might have missed a deviation (e.g. that a simply language is permitted without variant). If that's the case, please open an issue and have me fix the check.
    Solution: either do not explicitly set a language preference via setLangPref() (Amazon then uses the default language for your location) – or specify a valid one.

Errors signaled from Amazon servers via HTTP Response codes

Amazon signals several errors via HTTP response codes. Not all of them are clear to me, so I cannot explain them all. For those I can I do. The error messages all follow the pattern of "Error connecting … got XXX", where XXX is the response code:

  • 429: You've hit your API Rate Limit.
    Solution: Not much you can do – except to "try again later".
  • 401: This can mean many things, to my experience. Ordinarily, this should only mean "Unauthorized" – i.e. your credentials are wrong. But during my tests, I've often got this instead of above 429. So no clear rules for it.
  • 400: This usually means something is wrong with your "payload" – so to help your investigation, it will trigger another E_USER_NOTICE including its definition. In most cases you've specified a category (aka SearchIndex) which is not valid (several of them have been renamed from PA API 4 to PA API 5 – e.g. DVD now is MoviesAndTV. And not all SearchIndexes are available for all locations. So that should be the first thing to check. It was always the culprit when I got a 400, so I cannot tell what else might render a request invalid (except for e.g. specifying a string that is not exactly 10 chars long to be used as ASIN).