Custom API for Magento 2

We have already went through on how to configure integration and utilize Magento apis. But let’s see how to make our own module with custom API calls.

Module Essentials

For a simpler start you should read the following article: “How to create a basic module in Magento 2” by Hrvoje Ivancic and make basic Magento 2 module. You would need only two things, module.xml and register.php for this example module. I would create module under Inchoo name space and call it Hello.

Module Configuration – etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Inchoo_Hello" setup_version="1.0.0" />

Registration – registration.php


API configuration

There are two more additional configurations we need to add API capability to module, webapi.xml and di.xml. In webapi.xml we are configuring access rights and API Interface that specified method will use.

Web API configuration – etc/webapi.xml

<?xml version="1.0"?>
<routes xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/hello/name/:name" method="GET">
        <service class="Inchoo\Hello\Api\HelloInterface" method="name"/>
            <resource ref="anonymous"/>

Resource tag defines what resources user needs to have to be able to access this api call. Possible options are self, anonymous or Magento resource like Magento_Catalog::products or Magento_Customer::group. We will for now use anonymous so we can access it as a guest.

Define Interface – etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Inchoo\Hello\Api\HelloInterface"
                type="Inchoo\Hello\Model\Hello" />

In di.xml we define what model will interface call to. We also need to add Interface and Model, please note that you need to take care about comments also.

Interface – Api/HelloInterface.php

namespace Inchoo\Hello\Api;
interface HelloInterface
     * Returns greeting message to user
     * @api
     * @param string $name Users name.
     * @return string Greeting message with users name.
    public function name($name);


Model – Model/Hello.php

namespace Inchoo\Hello\Model;
use Inchoo\Hello\Api\HelloInterface;
class Hello implements HelloInterface
     * Returns greeting message to user
     * @api
     * @param string $name Users name.
     * @return string Greeting message with users name.
    public function name($name) {
        return "Hello, " . $name;

Within model we add our functionality that will be executed by call to API method. In this case it will append Hello to name provided by call and return as string.

With all this your module should look like this:



Communicating with new API call

Testing as guest

To test REST you can go to http://{domain_name}/rest/V1/{method}/{attribute}/{value}.

Example: http://magento2.loc/rest/V1/hello/name/Jim

This is how response should look like for this example:

<response>Hello, Jim</response>

Here is small code that will test same API call but with SOAP:

$proxy = new SoapClient('http://magento2.vm/index.php/soap/default?wsdl&services=inchooHelloV1');
$result = $proxy->inchooHelloV1Name(array("name"=>"Jim"));

Response for SOAP

object(stdClass)#2 (1) {
  string(10) "Hello, Jim"

Adding ACL

If we don’t set anonymous in resource of webapi.xml, we need to set existing Magento resource or create our own. We can do that by adding acl.xml to etc.

ACL – etc/acl.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
            <resource id="Magento_Backend::admin">
                <resource id="Inchoo_Hello::hello" title="Hello" translate="title" sortOrder="110" />


In this case we need to add “Inchoo_Hello::hello” to webapi.xml resource instead anonymous.

In article Magento 2 API usage with examples by Tomas Novoselic is covered how we can connect to Magento with REST or SOAP API and we can use the same example to create new integration and test new implementation of API call.

Since Magneto 2 is still fresh this may change in time, but we will try to keep this up to date with latest version. This is tested with Magento v2.1.0.



  1. is it possible for magento 1?. I want to create the same module for magento 1 .


  2. Hi,
    Do you know how to return a json response instead of string ? I tried with this , but no luck :
    $result = $this->resultJsonFactory->create();
    $result->setDate([‘success’ => true]);

    Returning a simple string works fine though.

  3. Great tutorial. Worked perfectly for me. Very clear instructions for a very complex system. Thank you!

  4. I think this is wrong http://{domain_name}/rest/V1/{method}/{attribute}/{value}. The method should probably be replace with class and the rest should also follow suit.

  5. Are you sure di.xml stands for “Define Interface”? Maybe “Dependency Injection”?

    1. Hi Rustem,
      in article, subheading “Define Interface” is not here to explain di in filename of di.xml but instead what is our goal by adding this file. But you make a valid point, subheadings are bit ambiguous I will look into fixing them. Thanks.

  6. Hi – Thanks for the warm up API article! I’m not getting the expected response though – even after enabling the Inchoo_Hello module (and doing the setup:upgrade, etc), I’m seeing a ‘Document is Empty’ response from the REST version.

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>.