Update Magento product using curl and the REST API

I just spent all afternoon teaching myself how to update a product in Magento using the REST API and curl. I started by building on the tutorial by Ashley Schroder which got me part of the way there, and then figured the rest out the hard way. There are many little gotchas that I encountered while I worked through this and I am pretty disappointed with the lack of information about using the Magento REST API – hope this helps you!

First I set up my REST API roles and attributes in the Magento admin. I had to enable the Admin role and then specifically set which actions I wanted to be available. There are other tutorials that cover this part thoroughly, so in a nutshell you just need to make sure that you:

  1. Configure roles (what can the REST API do?)
  2. Configure attributes (which model attributes can be read/written by the REST API?)
  3. Create a REST API consumer and record the consumer_key and consumer_secret
  4. Associate your admin user to a REST API role
  5. Allow the REST API Guest role to view products (this will help greatly when debugging)

Then you will need to generate an OAuth token. You can try doing it the way Ashley describes by using the oauth Ruby gem, or you can do it the way I did by following the instructions for retrieving a product using the Admin REST API role found on Magento’s site.

It took me quite a while to actually get my token. I ended up having to modify Zend_Controller_Request_Http::getHeader to correct for the fact that my host does not have the function apache_request_headers enabled (for those of us using php-fpm this will always be the case. This StackOverflow answer was what finally pointed me in the right direction.

Once you have your access token and the accompanying secret you can use the oauth Ruby gem to get the nonce, timestamp, and signature that you will need to perform your PUT request and update a product using curl. Here is what that looks like:

You can see the response from oauth beginning on line 10. This is what I used to substitute into the following curl request. You will need to replace the nonce, timestamp, and signature values with your own. Note the use of the –method parameter in the OAuth request to indicate that we want to perform a PUT request. This tripped me up for a while. The default is GET and if you don’t include method you’ll get a signature mismatch. Note also that I’m passing the OAuth authorization details using a header instead of in the querystring like other examples on the web. The querystring method did not work for me.

You might also note the duplicate Content-Type and Content_Type headers. This little gotcha stopped me in my tracks for a while until I found this post on the Magento boards.

Finally, you can issue a curl request using the values from the OAuth request dance that will – if your roles and attributes are configured correctly – update a product in Magento. The product data that you want to update is passed using curl’s -d parameter as a JSON string containing as many attribute name and value pairs as you want to update. Note that you cannot pass the text values for dropdown attributes – you need to use their option ID values. This seems like a disappointing half-implementation of a very useful feature to me, but then again, I’ve come to expect this sort of stuff when working with Magento!

During my research I also successfully created a product using the PHP OAuth library and the examples provided by Magento. The file I created to do that is in the gist below. Remember to update your consumer_key, consumer_secret, and URLs to your own. There are a few weird behaviours I noticed:

  1. When you create a product using the REST API, you can not actually retrieve it using the REST API until you save the product. This is explained further in a Magento StackExchange post.
  2. I received a 401 error every time a product was created successfully that indicated the same nonce had been used before. I tracked this down to /app/code/core/Mage/Api2/Model/Resource.php on line 227, where after creating a product the default response is to return a Location header which sends the client to the REST response with details of the newly-created product. I am unsure of the resolution but know that it has something to do with the way the PHP OAuth library negotiates the Location header it receives. I did not pursue this further – the product was being created fine and that was ok by me!

That concludes my exploration of Magento’s REST API and I hope this synthesis helps you in your own research.

About Drew

Since 2001, I have applied my expertise to clients in the advertising, retail, philanthropic, travel/tourism, real estate, and healthcare industries.

Leave a Reply