Magento API v2 SOAP demystified

Featured Image ©

Last few weeks, i often see confused people asking questions about difference between Magento’s API v1 and v2, and also bunch of questions about how to use WSDL and WS-I files when developing own or extending existing Magento soap API v2.
It is obvious that short articles about specific Magento API parts will not help them to get the bigger picture about Magento core API v2. Because of that, I decided to demystify practical usage of Magento API v2 and also to explain difference when using v1 and/or v2 API.

Let’s start from beginning, to everything clear later:

SOAP basics

SOAP = Simple Object Access Protocol. It is based on XML mostly via HTTP (POST).
Soap basic structure is basically Envelope with Header and Body inside:

Soap structure

Soap structure

Some example SOAP message looks like this:

POST /InStock HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 299
SOAPAction: ""
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="">
     <m:GetStockPrice xmlns:m="">


WSDL stands for: “Web Services Description Language”. It is basically XML – based language that is used for describing the functionality offered by a web service.

There are two possible versions of WSDL: WSDL 1.1 and WSDL 2.0. Since Magento uses WSDL 1.1, I will continue with this WSDL version in this article.

Objects in WSDL

Magento Core API

There are two API types present in Magento by default (I am talking about Magento versions 1.6.2CE and below):

  • SOAP (API v1 and v2)

More on API types and differences you can find in post: Consuming SOAP web services in iOS by Ivan Kalaica

Accessing Magento API via SOAP – basic steps

  1. Create appropriate role (Magento Admin)
  2. Create web services user (Magento Admin)
  3. Assign created role to the user (Magento Admin)
  4. Log-in to web service and retrieve Session Id (Soap Client)
  5. Call appropriate method (Soap Client)

Creating Web Service Role

First we should define appropriate roles for web services user, so, log-in to admin panel, go to menu: System/Web services/Roles and click on Add New Role button.

On “Role info” tab, we need to enter some custom Role name, and then click on Role resources tab, choose wanted role resources and Save Role.

Role resources necessary for usage with API are basically defined in each Magento module’s api.xml file in etc folder, and can be checked there what role resources are needed for successful consuming specific API method.

Creating Web Service User

After creating role, let’s create web services user that will have defined role permissions.
Go to menu: System/Web Services/Users and click on “Add New User” button. Under “User Info” tab fill the fields, and pay attention that “User Name” and “API key” values are values that we will use on client side to access API.

Assigning created Role to the User

After that, we just have to click on User Role tab and click on radio-button to assign wanted role to current user.
After that we just need to click Save User button.

Calling Magento API v1 methods

$api_url_v1 = "http://magento.local/api/soap/?wsdl=1";
$username = 'mobile';
$password = 'mobile123';
$cli = new SoapClient($api_url_v1);
//retreive session id from login
$session_id = $cli->login($username, $password);
//call customer.list method
$result = $cli->call($session_id, 'customer.list', array(array()));

Calling Magento API v2 methods

$api_url_v2 = "http://magento.local/api/v2_soap/?wsdl=1";
$username = 'mobile';
$password = 'mobile123';
$cli = new SoapClient($api_url_v2);
//retreive session id from login
$session_id = $cli->login($username, $password);
//call customer.list method
$result = $cli->customerCustomerList($session_id);

If you compare those two versions of API calls, you will notice that v1 uses method “call” for ever requested method, and v2 has defined full method name to call.

//API v1 way
$result = $cli->call($session_id, 'customer.list', array(array()));
//API v2 way
$result = $cli->customerCustomerList($session_id);</pre>

Basically, API v2 calls method same way like v1, but there is some kind of wrapper around call method in v2. Somebody will ask: Why Magento did something like this? Why would somebody make different methods for accessing API when we have “call” method already?

Here comes the basic difference between v1 and v2 API in Magento.

To demystify that, we should first look at and compare WSDL for v1 and v2 API in Magento.

If we open url: we can see that few basic method are inside: call, multiCall, login etc…
But, if we look at, we will find that there is bunch of methods defined inside.

Imagine that you want to use some generator for SOAP methods to auto-generate your client-side classes end entities for consuming web services.
When using WSDL generated for API v1, we could just generate those few methods which will not tell to our source code generator what methods are available, and what parameters for each methods can we use, what entities we should have on client side … but if we are consuming web services through v2 API, it’s already served for us inside WSDL…


When using Magento v1 API, we access resources via call method and provide API method name and parameters as parameters of call method.

When using Magento v2 API, we access resources via real method name and we provide parameters as defined in WSDL for each specific method.

OK. When we got this difference, and showed how to consume SOAP, let’s focus on creating own web service methods compatible with API v2.

Practical example: Creating own API v2 method

Basic steps:

1. Create Magento Extension (we are not going explain here how to do it)
2. Create Model for API method
3. Create and configure api.xml file
4. Create wsdl.xml file (with proper definitions)
5. Create wsi.xml file (with proper definitions) (OPTIONAL)

Creating Model for API v2

After properly configuring our config.xml it looks like this:

<?xml version="1.0"?>

Let’s navigate through Magento core files to see where Magento API models are in file-system:

Since we are going to use API v2 only, We will create our model like this:

Creating and configuring api.xml

The easiest way is to copy/paste one of Magento’s api.xml files in our etc folder and make changes there to suit our needs. Our final api.xml should look like this:

<?xml version="1.0"?>
            <title>Inchoo Customer's Groups API</title>
              <list translate="title" module="inchoo_mapy">
                  <title>Retrieve customer groups</title>
           <mapy_data translate="title" module="inchoo_mapy">
              <title>Mapy data</title>

Here is logic that has to be implemented in api.xml file. Api.xml file basically connects API calls with php methods inside specific models. Also, the ACL resources are defined here for specific api call.

Creating wsdl.xml file

When working with wsdl.xml and wsi.xml later, if you are happy NetBeans user, I strongly suggest you to search on Google and download the XML Tools plug-in that can make life much easier …

There are few things that we have to fill-in when creating wsdl.xml.

  • Bindings
  • Port types
  • Messages
  • Types / Complex types

Also, it’s easier to copy one of Magento’s wsdl files, paste it in our etc folder and remove unnecessary things and add our own inside.

Here is NetBeans – XML Tools screen-shot how this look like:

This  image is showing logic and direction how should we fill-in wsdl.xml:

Let’s now look at real xml source:

After we finished with wsdl, let’s go to http://ourmagento/api/v2_soap/?wsdl=1 to see changes in global wsdl we made. (Don’t forget to clear cache first!).

We can see that all wsdl.xml files including ours are rendered as single.

All available wsdl definitions for current Magento installations are shown and our definitions should be there.

Now we are ready to use our newly created SOAP method.

But, if we want use some generator for client classes with that, for example SUDZC ( we need to make one more thing in order to make it possible…


– WSI is in basic compatibility layer for different frameworks and provides a little bit more information that can be used for example with XSLT to transform definitions into our client source code.
– It’s not essential in order web services to work.
– It is rendered when: Magento admin: System/Configuration/Services/Magento core API/WSI-Compliance configuration value is set to “YES”.

We could say that following sections we have to fill-in inside, in order to add our definitions properly:

  • Bindings
  • Port types
  • Messages
  • Types / elements
  • Types / complex types

Let’s copy/paste one of Magento’s wsi.xml inside our etc folder first. After that, let’s delete all unnecessary definitions for our SOAP method.

Adding definitions inside WSI except for slightly different definitions are basically the same as for wsdl.xml. If you are using existing wsi.xml, it’s easy to delete unnecessary and rename few nodes to suit your needs. Just follow the rule to fill all of this in the above list (Bindings, Port types … ).

Here you can download archive with basic wsdl.xml, wsi.xml, api.xml so you can easier start writing your own web service methods. Just put these files in your etc folder, rename appropriate things with your own and that’s it.

That would be all for now. If interested in Magento API, stay tuned.

Cheers 🙂


  1. Hi,
    This tutorial is working great..
    But do you have any tutorial which shows how to call and use Magento SOAP v1 APIs from JavaScript??
    I am currently stuck with this functionality…

  2. Hi, i would like to call Magento API functions from 3rd party frameworks, would working wiith API be thee right way?

  3. Is there any way to make a multicall sort of thing with Magento SOAP V2? I need to fetch details of multiple products in one call and i’m unable to do so with V2.

    1. No, you should use v1 api for multi-call. Only possibility that comes to my mind is to create a custom SOAP API method which will do multi operations and expose single SOAP method to wsdl

  4. This is very interesting. Do you have a solution to update products in a order?

    We add some custom attributes to our products, like “product_processing_status”.
    Now we have a order with some products.

    I read the product data from the order with the SOAP V2 API.
    How i can retrieve the custom attribute “product_processing_status” with SOAP V2 and update them with a new value in the order?

    Do you have any ideas?

  5. when i used the url of then showing :
    SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘’ : failed to load external entity “”

  6. I am unable to pass params through api, call. works in local but not in live. cleared cache but still doesn’t work 🙁

    $result = $cli->as400Index($sessionId, 'catalog_product_price_index_1,catalog_product_price_index_2', 'cp', 'fc');

    any idea?

  7. I’m trying to connect with magento allocated in a remote server using your instructions but I get Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘’ : failed to load external entity “”.
    But when i try the same code on my local magento it’s work properly, and they have the same configuration, users and roles.

    $api_url_v1 = “”;
    $username = ‘appmkt’;
    $password = ‘mktapp2014’;
    $cli = new SoapClient($api_url_v1);
    //retreive session id from login
    $session_id = $cli->login($username, $password);
    //call customer.list method
    $result = $cli->call($session_id, ‘customer.list’, array(array()));

    Is there any special method to connect with magento in a remote server?


  8. Hi I am trying to use SOAP, however I am facing the following error:

    API type “soap” is not supported

    #0 /mnt/webapp/besttoys/besttoys/app/code/core/Mage/Api2/Model/Server.php(197): Mage_Api2_Model_Config->getRoutes(‘soap’) #1 /mnt/webapp/besttoys/besttoys/app/code/core/Mage/Api2/Model/Server.php(105): Mage_Api2_Model_Server->_route(Object(Mage_Api2_Model_Request)) #2 /mnt/webapp/besttoys/besttoys/api.php(69): Mage_Api2_Model_Server->run() #3 {main}

    Could someone help me on it. I am

  9. Hi,

    I dont want to load wsdl.xml file of Catalog and Sales module in my SOAP WSDL Url.

    Hos can i do that?

  10. Hi,
    Iam new to magneto can you please tell where i put SOAP connection file and the folder structure.

  11. Hi,

    I have a cluster of servers (2 frontend, 1 database-write and 1 database-read) and I install the admin panel in the server of database-write with the domain name

    But I can’t make the Web services works with the domain because Magento redirects everything to the domain

    The admin panel works fine, but the Web services doesn’t works with the custom admin url.


  12. session_start();
    $host = ‘http://localhost/megento/api/v2_soap/?wsdl’;
    $api = ‘testkey’;
    $user = ‘test’;
    $client = new SoapClient($host);
    $session = $client->login($user, $api);
    $complexFilter = array(
    ‘complex_filter’ => array(
    ‘key’ => ‘type’,
    ‘value’ => array(‘key’ => ‘in’, ‘value’ => ‘simple’)
    $SimpleProducts = $client->catalogProductList($session, $complexFilter);


    Above php code is not working for me. The code is used to get list of simple products.
    Any admin settting needed for that ? i have created user and assign role to it.
    please help.

  13. Hi,
    my page goes blank when i put wrong “magento go” url.i want to catch the error when url goes wrong. but due to blank and no response from server i cannot do so please tell me what should be my apporach

  14. Attached is an example set of code that is failing with the error “ Unknown error”.
    MagentoService magentoV2 = new MagentoService();
    MageApiModelServerWsiHandlerPortType portV2 = magentoV2.getMageApiModelServerWsiHandlerPort();
    LoginParam loginParam = new LoginParam();
    loginParam.setApiKey(new com.moment.connector.magento.soap.v2.String(“12341234”));
    loginParam.setUsername(new com.moment.connector.magento.soap.v2.String(“testuser”));
    LoginResponseParam loginResponse = portV2.login(loginParam);

    com.moment.connector.magento.soap.v2.String sessionId = new com.moment.connector.magento.soap.v2.String(loginResponse.getResult().getValue());
    com.moment.connector.magento.soap.v2.String storeId = new com.moment.connector.magento.soap.v2.String(“1”);

    List calls = new ArrayList();
    // Create the shopping cart
    ShoppingCartCreateRequestParam shoppingCartCreateRequestParam = new ShoppingCartCreateRequestParam();

    MultiCallParam multiCallParam = new MultiCallParam();
    MultiCallResponseParam multiCallResponseParam;
    try {
    multiCallResponseParam = portV2.multiCall(multiCallParam);
    System.out.println(“” + multiCallResponseParam.getResult());
    } catch (Exception e) {

  15. I am trying to use the multicall option in the java soap v2 api. Any ideas how to make the calls to it? I am not finding anything online to give greater clarity as to the types of objects that will be sent to the server.

  16. I got it working like this.

    $cli = new SoapClient($api_url_v2);
    $session_id = $cli->login(array('username'=>$username, 'apiKey'=>$password));
    //retreive session id from login
    $result = $cli->customerCustomerList(array('sessionId'=>$session_id));

    but i am not able to print the customer list, neither is there any exception

  17. I am trying to use Magento web services by posting SOAP_V2 XML. I’m having lots of success but one attribute that I receive, group_price, has a value of “array”. It’s not surprising to me that group_price is an array. But how can I specify in the XML that I want to retrieve the group_price for customer_group=4 ?

  18. Hi,

    Im getting some troubles creating a custom methods in the SOAP Service of Magento, but this problems happens when the Page Cache is active, otherwise it works just fine, and when I activate the cache the connection with the web service displays an error that can’t find definitions in the wsdl.

    I don’t know if having the Page Cache disable can damage the performance of my store.

  19. Hi,

    i am trying to use magento web service with java. Could you please help me with this?

  20. Hi Darko,
    I stucked at one point while trying to create the webservice with reference of this post.

    All the parameters are displaying in the WSDL file when its viewed from browser with the URL. I mean complextype, request/response param and request/response messages.

    But my method is not being displayed when I make call to $cli->__getFunctions().

    Can you please help what am I doing wrong?

  21. I enjoyed the read. There is limited information on this subject and your article was helpful. However, I have an error that I can not source and repair. I am using Community V. 1.7.02 and I am trying to use SOAP V2 and I am getting an error message:

    SoapHeaderException: Procedure ‘login’ not present

    error: html/lib/Zend/Soap/Server.php on line 832

    When I checked the file and line specified my file is identical to the original file from magento download. (I can post the line if you would like). I am unsure how to fix this, nor do I have a clue where to look next for the source of the error. Any clues or help will be appreciated.

  22. Which SOAP Version has better performance V1 or V2?

    I think is V1 by using multiCall.

    Is there a method in V2 similar to multiCall in V1?

    Thanks in Advance…. Great Post 🙂

  23. Hi,

    Could you please suggest where (which folder) to put this wsdl.xml? I have created the extension and put api.xml and config.xml in etc folder. But not sure about wsdl.xml.



  24. Could you please clarify what is this password (mobile123) in the code snippet below:

    While creating webservice user and roles in magento admin, we do not specify any password there.

    $session_id = $cli->login($username, $password); // I get error at this point in the code

    login($username, $password);

    //call customer.list method
    $result = $cli->customerCustomerList($session_id);

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.