How can i subscribe newsletter in Magento2 using REST API

No need for any custom API, you can use the customer edit endpoint

EndPoint  = "/V1/customers/{customer_id}"

Method = "PUT"

Json  = 
{
  "customer": {
    "id": {customer_id},
     "email": "{customer_email}",
    "firstname": "{customer_firstname}",
    "lastname": "{customer_lastname}",
    "store_id": {store_id},
    "website_id": {website_id},
    "extension_attributes": {
     "is_subscribed": true
    }
  }
}

Please replace {customer_id}, {customer_email}, {customer_firstname}, {customer_lastname}, {store_id}, {website_id} with the customer information.

this was tested and worked for me


1 Create a module Test_Demo

2 Create webapi.xml

app/code/Test/Demo/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/newsletter/" method="POST">
        <service class="Test\Demo\Api\NewsLetterSubscriptionInterface" method="postNewsLetter"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
        <data>
            <parameter name="customer_id" force="true">%customer_id%</parameter>
        </data>
    </route>
</routes>

3 Create di.xml

app/code/Test/Demo/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="Test\Demo\Api\NewsLetterSubscriptionInterface" type="Test\Demo\Model\NewsLetterSubscription" />
</config>

4 Create Interface File

app/code/Test/Demo/Api/NewsLetterSubscriptionInterface.php

<?php
/**
 * A Magento 2 module named Test/Demo
 * Copyright (C) 2018  
 */

namespace Test\Demo\Api;

interface NewsLetterSubscriptionInterface
{

    /**
     * POST for newsletter api
     * @return string
     */

    public function postNewsLetter();


}

5 Create model file

app/code/Test/Demo/Model/NewsLetterSubscription.php

<?php
/**
 * A Magento 2 module named Test/Demo
 * Copyright (C) 2018 
 * 
 */

namespace Test\Demo\Model;
use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;

class NewsLetterSubscription implements \Test\Demo\Api\NewsLetterSubscriptionInterface
{

    /**
     * @var \Magento\Framework\App\RequestInterface
    */

    protected $_request;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var CustomerRepository
     */
    protected $customerRepository;

    /**
     * @var \Magento\Newsletter\Model\SubscriberFactory
     */
    protected $subscriberFactory;

    /**
     * @var \Magento\Newsletter\Model\Subscriber
     */
    protected $_subscriber;

    /**
     * Initialize dependencies.
     * @param \Magento\Framework\App\RequestInterface $request
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param CustomerRepository $customerRepository
     * @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
     * @param \Magento\Newsletter\Model\Subscriber $subscriber
     */

   public function __construct(    
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    CustomerRepository $customerRepository,
    \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory,
     \Magento\Newsletter\Model\Subscriber $subscriber
    )
    {
        $this->_request = $request;
        $this->storeManager = $storeManager;
        $this->customerRepository = $customerRepository;
        $this->subscriberFactory = $subscriberFactory;
        $this->_subscriber      = $subscriber;

    }

    /**
     * {@inheritdoc}
    */

    public function postNewsLetter()
    {
        $customerId = (string)$this->_request->getParam('customer_id');
        if ($customerId == null || $customerId == '') {

            return 'Something went wrong with your newsletter subscription.';

        }else
        {
            try {               
                    $customer = $this->customerRepository->getById($customerId);
                    $storeId = $this->storeManager->getStore()->getId();
                    $customer->setStoreId($storeId);
                    $this->customerRepository->save($customer);

                    if ((boolean)$this->_request->getParam('is_subscribed',false)) 
                    {

                        $this->subscriberFactory->create()->subscribeCustomerById($customerId);
                        return 'You have successfully subscribed! Thanks for subscribing to our newsletter!';

                    } else {

                        $this->subscriberFactory->create()->unsubscribeCustomerById($customerId);               
                        return 'You have successfully unsubscribed!';
                    }

            } catch (\Exception $e) {

                return 'Something went wrong with your newsletter subscription.';

            }
        }


    }

}

6 Open postman application and testing the same.

Note: Here I am providing logic based on the customer Id. you can change the logic as per your requirement.