Build Your Own Magento 2 Custom API

Build Your Own Magento 2 Custom API

CYou need a custom API in Magento 2 when default endpoints don't cut it. Custom APIs let you connect Magento stores with ERP systems, mobile apps, CRM platforms, and third-party services that require specific data formats or functionality beyond what's built-in.

Why Build Custom APIs

Default Magento APIs work for standard operations, but custom business logic demands tailored endpoints. You might need to:

  • Sync inventory data with warehouse management systems
  • Push order information to accounting software
  • Pull customer data into marketing automation tools
  • Enable headless commerce architectures
  • Power mobile apps and progressive web applications with custom data structures

Speed matters too—custom APIs deliver precise data without frontend overload, reducing latency and improving load times.

Tip

To enhance your eCommerce store’s performance with Magento, focus on optimizing site speed by utilizing Emmo themes and extensions. These tools are designed for efficiency, ensuring your website loads quickly and provides a smooth user experience. Start leveraging Emmo's powerful solutions today to boost customer satisfaction and drive sales!

Core Components You Need

Every custom API requires four files:

File Purpose / Location
API Interface Defines methods and parameters
Location: Api/ folder
Implementation Class Contains business logic
Location: Model/ folder
webapi.xml Registers routes and authentication
Location: etc/ folder
di.xml Maps interface to implementation
Location: etc/ folder

Step 1: Set Up Your Module

Create module.xml first:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">

<module name="YourNamespace_CustomAPI" setup_version="1.0.0"/>

</config>

Add registration.php:

<?php

\Magento\Framework\Component\ComponentRegistrar::register(

\Magento\Framework\Component\ComponentRegistrar::MODULE,

'YourNamespace_CustomAPI',

__DIR__

);

Step 2: Define Your API Interface

Your interface must include doc-blocks with @api, @param, and @return annotations or it won't work.

Create Api/ProductLookupInterface.php:

<?php

namespace YourNamespace\CustomAPI\Api;

interface ProductLookupInterface

{

/**

* Retrieve product by custom code

*

* @api

* @param string $code

* @return \Magento\Catalog\Api\Data\ProductInterface

* @throws \Magento\Framework\Exception\NoSuchEntityException

*/

public function getByCustomCode($code);

}

When you extend AbstractHelper, you get the scopeConfig property automatically without injecting it.

Method 2: Direct Injection (Recommended for Magento 2.4.5+)

Starting with Magento 2.4.5, inject ScopeConfigInterface directly instead of extending AbstractHelper:

<?php

namespace Vendor\Module\Helper;

use Magento\Framework\App\Config\ScopeConfigInterface;

use Magento\Store\Model\ScopeInterface;

class Config

{

    const XML_PATH_GENERAL = 'module_settings/general/';

    protected $scopeConfig;

    public function __construct(ScopeConfigInterface $scopeConfig)

    {

        $this->scopeConfig = $scopeConfig;

    }

    public function getConfigValue($path, $storeId = null)

    {

        return $this->scopeConfig->getValue(

            $path,

            ScopeInterface::SCOPE_STORE,

            $storeId

        );

    }

    public function isEnabled($storeId = null)

    {

        return (bool) $this->getConfigValue(

            self::XML_PATH_GENERAL . 'enabled',

            $storeId

        );

    }

}

Step 3: Build the Implementation

Create Model/ProductLookup.php:

<?php

namespace YourNamespace\CustomAPI\Model;

use YourNamespace\CustomAPI\Api\ProductLookupInterface;

use Magento\Catalog\Api\ProductRepositoryInterface;

use Magento\Framework\Exception\NoSuchEntityException;

class ProductLookup implements ProductLookupInterface

{

private $productRepository;

public function __construct(ProductRepositoryInterface $productRepository)

{

$this->productRepository = $productRepository;

}

public function getByCustomCode($code)

{

try {

return $this->productRepository->get($code);

} catch (NoSuchEntityException $e) {

throw new NoSuchEntityException(

__('Product with code "%1" not found', $code)

);

}

}

}

Step 4: Register Your API Route

Create etc/webapi.xml:

<?xml version="1.0"?>

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

<route url="/V1/products/lookup/:code" method="GET">

<service class="YourNamespace\CustomAPI\Api\ProductLookupInterface"

method="getByCustomCode"/>

<resources>

<resource ref="anonymous"/>

</resources>

</route>

</routes>

Authentication Options

Magento 2 supports three authentication types:

Token-Based: Generate tokens with username and password. Best for backend integrations.

Session-Based: Uses server-generated session IDs. Good for frontend requests.

OAuth: Uses authorization tokens. Required for third-party apps.

Change <resource ref="anonymous"/> to control access:

  • anonymous - Anyone can call
  • self - Authenticated customers only
  • Magento_Catalog::products - Admin users with specific permissions

Step 5: Configure Dependency Injection

Create etc/di.xml:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

<preference for="YourNamespace\CustomAPI\Api\ProductLookupInterface"

type="YourNamespace\CustomAPI\Model\ProductLookup" />

</config>

This maps your interface to its implementation class.

Step 6: Enable and Deploy

Run these commands:

php bin/magento setup:upgrade

php bin/magento setup:di:compile

php bin/magento cache:flush

Testing Your API

Check your API documentation at /swagger on your domain.

Test with Postman or curl:

curl -X GET \

"https://your-store.com/rest/V1/products/lookup/ABC123" \

-H "Content-Type: application/json"

Expected response:

{

"id": 1234,

"sku": "ABC123",

"name": "Sample Product",

"price": 99.99,

"status": 1

}

Error Handling Best Practices

Always throw specific exceptions:

throw new \Magento\Framework\Exception\NoSuchEntityException(

__('Resource not found')

);

throw new \Magento\Framework\Exception\LocalizedException(

__('Invalid input data')

);

Use input validation and output escaping to prevent security vulnerabilities.

REST vs SOAP APIs

REST uses lightweight JSON for fast, efficient data transmission. SOAP relies on XML and provides more structure but adds overhead. REST works better for mobile apps and modern integrations.

Performance Tips

Custom APIs improve site speed by delivering only necessary data, reducing server response times through efficient endpoints, and enabling smart caching strategies.

Keep responses lean:

  • Return only requested fields
  • Implement pagination for large datasets
  • Use proper indexing on database queries
  • Cache frequently accessed data

When to Create Custom APIs

Build custom endpoints when you need to:

  • Integrate with ERP systems, custom mobile apps, or create multichannel experiences
  • Implement complex business logic
  • Optimize performance for specific use cases

API versioning lets multiple versions coexist, enabling backward compatibility when updating endpoints.

Conclusion

Your custom API now connects external systems to your Magento store. Test thoroughly with different authentication methods. Monitor API performance and adjust as needed.

FAQs

What is a custom API in Magento 2?

A custom API in Magento 2 allows you to expose your own endpoints to interact with your store's data or functionality. It can be REST or GraphQL-based and is useful for integrating with external systems, apps, or custom frontends.

Why should I build a custom API instead of using default APIs?

Default Magento APIs provide standard functionality, but custom APIs let you tailor endpoints to your specific business needs, simplify complex workflows, and expose only the data or actions required by your application.

How do I create a custom REST API in Magento 2?

To create a custom REST API, follow these steps:

  • Define a new module with module.xml and registration.php.
  • Create a web API configuration in webapi.xml specifying the route, HTTP method, and interface.
  • Implement the interface in a PHP class to handle the logic.
  • Set proper ACL permissions to control access.

Can I create a GraphQL API for my custom module?

Yes. To create a GraphQL API:

  • Define your schema in schema.graphqls file.
  • Create resolvers for each query or mutation.
  • Register your module so Magento can expose the GraphQL endpoints.

How do I secure my custom API?

Magento provides built-in security via authentication and authorization:

  • Use OAuth or token-based authentication for REST APIs.
  • Set proper ACL rules in acl.xml for admin access.
  • Limit sensitive data exposure and validate all inputs.

How do I test my custom API?

You can test your API using tools like Postman, cURL, or GraphQL Playground. Ensure that requests return the expected data and errors are handled correctly.

Can I use dependency injection in my API classes?

Yes, always use dependency injection for services, repositories, and other Magento classes. This ensures your API follows Magento's best practices and is easier to maintain and test.

How do I version my custom API?

Include the API version in your webapi.xml route, e.g., /V1/custom/endpoint. This allows you to release updates without breaking existing integrations.

Are there best practices for building custom APIs in Magento 2?

Yes. Follow these guidelines:

  • Keep endpoints simple and focused.
  • Use proper HTTP methods (GET, POST, PUT, DELETE).
  • Validate inputs and handle exceptions gracefully.
  • Document endpoints clearly for developers.
  • Secure APIs with authentication and ACL rules.