Custom REST API Endpoint in Magento 2 | From webapi.xml to the Token
AI generated
Magento 2 · REST API

Custom REST API Endpoint
from webapi.xml to the token

A custom Magento 2 REST endpoint needs more than just a URL. What matters is a service contract, webapi.xml, ACL, clean dependency injection and a clear authentication strategy.

13 min read PHP 8.4 Magento 2.4.8

1. What a good endpoint needs to deliver

A custom REST API endpoint in Magento 2 is not simply a technical entry point. It is part of your public or internal system boundary. Other systems, frontends, integrations or middleware rely on the endpoint being stable, documentable and permission controlled. That is exactly why a custom endpoint should never be built like a quick controller hack.

A clean Magento endpoint is based on service contracts. That means the actual behavior lives in an API interface and its implementation, not directly in a route or in an unstructured class. webapi.xml connects the HTTP method and URL to this service layer. ACL resources define who is allowed to call the endpoint. Token or session context decides on authentication. When these parts are cleanly separated, the API stays maintainable.

For this tutorial we will build a simple endpoint that returns a greeting message. The business example is deliberately small so the technical structure stays clear. In real projects the same setup can be used for stock queries, ERP synchronization, CRM integrations or headless functionality. The decisive point is this: a custom REST API endpoint in Magento 2 should always be designed like a service, not like an isolated request handler.

2. Service contract and interface

The first building block is the API interface. If you want to build a custom REST API endpoint in Magento 2, you should formulate the public method as a service contract first. This contract defines inputs, return values and exceptions. That way, not only REST but also other Magento code can later use the same function.

In the example we place the interface under app/code/Mironsoft/ApiDemo/Api/HelloInterface.php. It contains a method getMessage() that returns a string. For more complex responses you would use data interfaces or DTO-like structures instead. What matters is that the contract stays explicit and does not depend on random arrays.


<?php
declare(strict_types=1);

namespace Mironsoft\ApiDemo\Api;

/**
 * Public service contract for the example REST endpoint.
 */
interface HelloInterface
{
    /**
     * Returns a greeting message for the API consumer.
     */
    public function getMessage(): string;
}

This step is often skipped when a team wants to ship quickly. But that is exactly where later problems begin. Without a service contract it stays unclear whether an endpoint carries the same responsibility internally and externally, how it is tested and what compatibility guarantees apply when it changes. A custom REST API endpoint in Magento 2 without an interface feels faster in the short term but costs more maintenance later.

3. Implementation and dependency injection

After the interface comes the implementation. It usually lives in Model or in a clearly scoped service class. The implementation should work on the business logic level and know nothing about REST-specific details. No reading of headers, no direct response manipulation, no URL logic. This separation makes the class testable and reusable.

In the example the implementation goes into app/code/Mironsoft/ApiDemo/Model/Hello.php. After that, etc/di.xml connects the interface with the concrete class. This is exactly how Magento uses dependency injection cleanly.


<?php
declare(strict_types=1);

namespace Mironsoft\ApiDemo\Model;

use Mironsoft\ApiDemo\Api\HelloInterface;

/**
 * Service implementation for the example REST endpoint.
 */
final class Hello implements HelloInterface
{
    /**
     * Returns the API greeting message.
     */
    public function getMessage(): string
    {
        return 'Hello from Mironsoft API Demo.';
    }
}

<?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="Mironsoft\ApiDemo\Api\HelloInterface"
                type="Mironsoft\ApiDemo\Model\Hello"/>
</config>

If the endpoint returns real data, this is where you inject repositories, SearchCriteriaBuilder, validators or other services. This is exactly the point where clean Magento architecture pays off. A REST endpoint should not work directly with the ObjectManager, and it should not start mixing SQL or collections wildly inside the service. The API layer benefits directly from the same standards as the rest of the application code.

4. webapi.xml and ACL

Now comes the actual REST exposure. The file app/code/Mironsoft/ApiDemo/etc/webapi.xml describes the URL, HTTP method, service class and ACL resource. This is where it is decided how Magento makes the endpoint available to the outside world. A custom REST API endpoint in Magento 2 does not live in the controller, but in the connection between the service contract and webapi.xml.

In the example we use a GET endpoint under /V1/mironsoft/hello. GET fits simple read operations. Write operations should choose POST, PUT or DELETE cleanly according to semantics. The ACL resource determines which tokens or user roles are allowed to use the endpoint.


<?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/mironsoft/hello" method="GET">
        <service class="Mironsoft\ApiDemo\Api\HelloInterface" method="getMessage"/>
        <resources>
            <resource ref="Mironsoft_ApiDemo::hello"/>
        </resources>
    </route>
</routes>

In addition, the module needs an ACL resource. It lives in etc/acl.xml. Without this resource the exposure is not clean. Many developers set anonymous too hastily on internal endpoints. That is only acceptable when the endpoint is genuinely public and technically harmless. For business or integration data, a targeted ACL is almost always the better choice.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Mironsoft_ApiDemo::root" title="Mironsoft API Demo" sortOrder="10">
                    <resource id="Mironsoft_ApiDemo::hello" title="Hello Endpoint" sortOrder="10"/>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

This separation matters: webapi.xml says which service is reachable over HTTP. acl.xml says who is allowed to use it. A robust custom REST API endpoint in Magento 2 needs both. Otherwise you quickly end up with endpoints that run, but are neither secure nor cleanly documented.

5. Token and authentication

The title of this topic explicitly mentions the token, and rightly so. A REST endpoint only becomes practically usable once it is clear how it gets authenticated. Magento offers several ways to do this: admin tokens, customer tokens, session-based contexts and anonymous endpoints. Which variant fits depends on the purpose of the API.

For internal integrations, back office synchronization or system-to-system communication, an admin token is often the simplest solution. For customer functionality in a headless frontend, a customer token is more relevant. Public endpoints should be used very sparingly and deliberately. Just because an endpoint can technically be exposed anonymously does not mean it makes sense from a business point of view.

A typical flow for an admin token begins with a request to /rest/V1/integration/admin/token. After that, the token is sent as a bearer token in the Authorization header. Only then can the ACL protected endpoint be called. This is the point where many tests fail: the endpoint itself is correct, but the wrong token or the wrong ACL blocks access.


curl -X POST "https://example.test/rest/V1/integration/admin/token" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"adminPassword"}'

curl -X GET "https://example.test/rest/V1/mironsoft/hello" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json"

For production integrations it also matters how tokens are rotated, logged and secured. A cleanly built custom REST API endpoint in Magento 2 does not end at the XML file. Operations, monitoring and access control belong to it, especially when ERP, PIM or external SaaS systems access the API.

6. Common mistakes

The most common mistakes with custom endpoints are surprisingly consistent. First, a class gets attached directly to webapi.xml without a service contract. Second, ACL gets defined too openly. Third, the implementation mixes HTTP logic, data access and business logic into a single class. Fourth, return values are built as loose arrays without a clear contract. Fifth, the API is only tested locally, never with a real token flow.

Another mistake is the wrong expectation for REST itself. Not every internal function automatically needs a REST endpoint. If a function is only accessed internally within Magento, a regular service is often enough. A custom REST API endpoint in Magento 2 makes sense when external or decoupled systems need to call the same function in a stable and controlled way.

Naming also matters. URLs like /V1/doSomething or /V1/customapi/test are technically possible, but poorly maintainable. Clearly named resources with business meaning are better. Anyone who takes APIs seriously builds not just the technology, but also an understandable interface.

7. REST endpoint vs. controller

A Magento controller and a REST endpoint look similar at first glance, because both respond to HTTP. The architectural difference is nonetheless significant. A controller is part of the web application and usually returns HTML or redirects. A REST endpoint is an API interface with a machine-readable contract, defined authentication and long-term integration responsibility.

Aspect REST endpoint Controller
Purpose Integration and API access HTML pages, form flows, redirects
Definition webapi.xml + service contract routes.xml + controller class
Security ACL, token, API context Session, form key, customer context
Contract Stable API contract UI-focused, less integration oriented

This comparison helps with architecture decisions. When an external app, an ERP or a headless frontend needs to access data, a clean endpoint is the right choice. When a Magento page needs to render HTML, a controller fits better. Misusing a controller as an API shortcut usually backfires quickly.

Mironsoft

Magento 2 API, modules and integrations

Want to integrate custom Magento endpoints cleanly?

We build Magento 2 REST APIs with service contracts, webapi.xml, ACL, clean DI and stable integration contracts for ERP, PIM, CRM and headless frontends.

API design

Clear URLs, clean service contracts and stable return structures

Security

ACL, token strategy and controlled permissions for integrations

Magento 2.4.8

PHP 8.4, dependency injection and modular interfaces without shortcuts

9. Summary

A custom REST API endpoint in Magento 2 consists of more than a URL. The clean path goes through service contract, interface, implementation, dependency injection, webapi.xml, ACL and a well thought out token flow. This separation makes the API testable, extendable and integration ready.

Anyone who takes fast shortcuts through controllers, the ObjectManager or unclear arrays only saves time in the short term. For production Magento integrations, a clean endpoint setup is almost always worth it, because later changes remain controllable.

Custom REST API Endpoint Magento 2: the essentials at a glance

Contract

Define the interface and service contract first, then expose it via REST.

Exposure

webapi.xml connects the URL, method and service method.

Security

Choose ACL and token strategy deliberately, do not default to anonymous access.

Architecture

Keep HTTP, business logic and data access separate, never misuse a controller shortcut as an API.

10. FAQ: Custom REST API Endpoint in Magento 2

1 What is a custom REST API endpoint in Magento 2?
A defined API route that gets connected to a service method through webapi.xml.
2 Does an endpoint need an interface?
For clean Magento architecture, yes. A service contract keeps the API testable and stable.
3 What is webapi.xml responsible for?
For URL, HTTP method and the mapping to a service method.
4 Does a REST endpoint need ACL?
Mostly yes. ACL defines who is allowed to use the endpoint and prevents overly open exposure.
5 What token types exist?
Typical types are admin tokens and customer tokens. The choice depends on the purpose of the API.
6 Controller or REST endpoint?
For integrations and APIs, a REST endpoint. For HTML, redirects and web flows, a controller.
7 Where does the implementation live?
In a service class that gets called via DI and preferably knows nothing about HTTP logic.
8 Can an endpoint use repositories?
Yes. That is often the cleanest way to separate data access from the API contract.
9 What is a typical mistake?
Missing interfaces, open ACL, ObjectManager usage and unclear array return values.
10 How do you test the endpoint?
With a real request, the correct HTTP method, token and ACL. Unit tests on the service level alone are not enough.