I have a EE 1.14 website whose product data we are updating with the SOAP API. I have come across an interesting problem related to 1.14 url keys and using SOAP. In 1.14 the url_key attribute must be set at store scope according to this document, http://devdocs.magento.com/guides/m1x/install/installing_upgrade_from-ee112.html. We have have multiple store views of which the url key is set at a global scope (the attribute is set to store scope, we just set it globally) so the product pages share the same url in different stores and this works fine AFAK. However when we update a product with the API only updating a couple of attributes, e.g

$data = array(
    'price' => 24.95,
    'special_price' => null

$product = $soap->catalogProductUpdate($session_id, "sku123", $data, 1, 'sku');

the whole product gets saved and all attributes that are set to store scope are saved with their global data, at the store scope passed. This would not be too much of a big deal for most attributes, just makes the db a bit bigger than it needs to be I guess, but for url_key in 1.14 it results in an error due to a unique key index on the value column of catalog_product_entity_url_key

If I updated at global scope the url_key doesn't get duplicated and all is fine. e.g

$data = array(
    'price' => 24.95,
    'special_price' => null 

$product = $soap->catalogProductUpdate($session_id, "sku123", $data, null, 'sku'); 

So my question, is there a tidy way to only update the passed product attributes via the API and leave the rest of the product as is? Or some other kind of work around so that we don't set the url at store scope for every product we update with the API.

Update - Turns out this isn't only a problem when using the API. In admin on the edit product page, if the admin user changes the scope to store view and saves the same thing happens

2 Answers 2


My solution in the end was to override Mage_Catalog_Model_Product_Api_V2::_prepareDataForSave in a custom extension with the following code:

 * Override core _prepareDataForSave so at store scope any url_key that isn't explicitly passed to the API
 * will be unset and not saved to db
 * @param Mage_Catalog_Model_Product $product
 * @param array $productData
protected function _prepareDataForSave($product, $productData)
    parent::_prepareDataForSave($product, $productData);

    if ($product->getStoreId() > 0) {

        /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
        foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) {

            $attrCode = $attribute->getAttributeCode();

            if ($attrCode == 'url_key' && $attribute->isScopeStore() && !property_exists($productData, $attrCode)) {
                $product->setData($attrCode, false);

Its not an ideal solution as if we do override url_key on a product and it is updated via the API the url_key will be set back to default. This is ok for this project as we only ever set url_keys globally. It might not work for everyone.

I also added a small bit of javascript to the admin product edit page to set the url_key field to always use default.

Still interested to hear other suggestions.


I had a similar problem loading products into Magento 1.9.2 using the V1 SOAP API. Despite passing a url_key, Magento seems to have changed it when I go to view the product after creating it via the API.

It seems to be related to scope, because the problem is only present on stores other than the default. It could be I'm misusing the API, but I am passing website_id and store_view_code...

Anyway, my 'solution' was to update the product after creating it via the API, passing the desired url_key the second time seems to get it to stick in Magento lol!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.