diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py
index 6c744d0dcef67fef1d8ac719eaba9420b530fe58..a9f224e152429624b6b5ce1808f1960a089c08f4 100644
--- a/src/compute/service/__main__.py
+++ b/src/compute/service/__main__.py
@@ -21,6 +21,7 @@ from common.Settings import (
 from .ComputeService import ComputeService
 from .rest_server.RestServer import RestServer
 from .rest_server.nbi_plugins.debug_api import register_debug_api
+from .rest_server.nbi_plugins.etsi_bwm import register_etsi_bwm_api
 from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
 from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss
 
@@ -59,9 +60,10 @@ def main():
     grpc_service.start()
 
     rest_server = RestServer()
+    register_debug_api(rest_server)
+    register_etsi_bwm_api(rest_server)
     register_ietf_l2vpn(rest_server)  # Registering L2VPN entrypoint
     register_ietf_nss(rest_server)  # Registering NSS entrypoint
-    register_debug_api(rest_server)
     rest_server.start()
 
     # Wait for Ctrl+C or termination signal
diff --git a/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Resources.py b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Resources.py
new file mode 100644
index 0000000000000000000000000000000000000000..38534b754d6c1ac502b21af55375c63159c57745
--- /dev/null
+++ b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Resources.py
@@ -0,0 +1,75 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy
+from common.Constants import DEFAULT_CONTEXT_NAME
+from flask_restful import Resource, request
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from .Tools import (
+    format_grpc_to_json, grpc_context_id, grpc_service_id, bwInfo_2_service, service_2_bwInfo)
+
+
+
+class _Resource(Resource):
+    def __init__(self) -> None:
+        super().__init__()
+        self.client = ContextClient()
+        self.service_client = ServiceClient()
+
+
+class BwInfo(_Resource):
+    def get(self):
+        service_list = self.client.ListServices(grpc_context_id(DEFAULT_CONTEXT_NAME))
+        bw_allocations = [service_2_bwInfo(service) for service in service_list.services]
+        return bw_allocations
+
+    def post(self):
+        bwinfo = request.get_json()
+        service = bwInfo_2_service(self.client, bwinfo)
+        stripped_service = copy.deepcopy(service)
+
+        stripped_service.ClearField('service_endpoint_ids')
+        stripped_service.ClearField('service_constraints')
+        stripped_service.ClearField('service_config')
+
+        response = format_grpc_to_json(self.service_client.CreateService(stripped_service))
+        response = format_grpc_to_json(self.service_client.UpdateService(service))
+
+        return response
+
+
+class BwInfoId(_Resource):
+
+    def get(self, allocationId: str):
+        service = self.client.GetService(grpc_service_id(DEFAULT_CONTEXT_NAME, allocationId))
+        return service_2_bwInfo(service)
+
+    def put(self, allocationId: str):
+        json_data = request.get_json()
+        service = bwInfo_2_service(self.client, json_data)
+        response = self.service_client.UpdateService(service)
+        return format_grpc_to_json(response)
+
+    def patch(self, allocationId: str):
+        json_data = request.get_json()
+        if not 'appInsId' in json_data:
+            json_data['appInsId'] = allocationId
+        service = bwInfo_2_service(self.client, json_data)
+        response = self.service_client.UpdateService(service)
+        return format_grpc_to_json(response)
+
+    def delete(self, allocationId: str):
+        self.service_client.DeleteService(grpc_service_id(DEFAULT_CONTEXT_NAME, allocationId))
+        return
diff --git a/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Tools.py b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..023d1006cd807ffeeed40d2e1e7273a580431073
--- /dev/null
+++ b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/Tools.py
@@ -0,0 +1,114 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import time
+from flask.json import jsonify
+from common.proto.context_pb2 import ContextId, Empty, EndPointId, ServiceId, ServiceTypeEnum, Service, Constraint, Constraint_SLA_Capacity, ConfigRule, ConfigRule_Custom, ConfigActionEnum
+from common.tools.grpc.Tools import grpc_message_to_json
+from common.tools.object_factory.Context import json_context_id
+from common.tools.object_factory.Service import json_service_id
+
+LOGGER = logging.getLogger(__name__)
+
+
+def service_2_bwInfo(service: Service) -> dict:
+    response = {}
+    # allocationDirection = '??' # String: 00 = Downlink (towards the UE); 01 = Uplink (towards the application/session); 10 = Symmetrical
+    response['appInsId'] = service.service_id.context_id.context_uuid.uuid # String: Application instance identifier
+    for constraint in service.service_constraints:
+        if constraint.WhichOneof('constraint') == 'sla_capacity':
+            response['fixedAllocation'] = str(constraint.sla_capacity.capacity_gbps*1000) # String: Size of requested fixed BW allocation in [bps]
+            break
+
+
+    for config_rule in service.service_config.config_rules:
+        for key in ['allocationDirection', 'fixedBWPriority', 'requestType', 'sourceIp', 'sourcePort', 'dstPort', 'protocol', 'sessionFilter']:
+            if config_rule.custom.resource_key == key:
+                if key != 'sessionFilter':
+                    response[key] = config_rule.custom.resource_value
+                else:
+                    response[key] = json.loads(config_rule.custom.resource_value)
+
+    
+    unixtime = time.time()
+    response['timeStamp'] = { # Time stamp to indicate when the corresponding information elements are sent
+        "seconds": int(unixtime),
+        "nanoseconds": int(unixtime%1*1e9)
+    }
+
+    return response
+
+def bwInfo_2_service(client, bwInfo: dict) -> Service:
+    service = Service()
+
+    for key in ['allocationDirection', 'fixedBWPriority', 'requestType', 'timeStamp', 'sessionFilter']:
+        if key not in bwInfo:
+            continue
+        config_rule = ConfigRule()
+        config_rule.action = ConfigActionEnum.CONFIGACTION_SET
+        config_rule_custom = ConfigRule_Custom()
+        config_rule_custom.resource_key  = key
+        if key != 'sessionFilter':
+            config_rule_custom.resource_value  = str(bwInfo[key])
+        else:
+            config_rule_custom.resource_value  = json.dumps(bwInfo[key])
+        config_rule.custom.CopyFrom(config_rule_custom)
+        service.service_config.config_rules.append(config_rule)
+
+    if 'sessionFilter' in bwInfo:
+        a_ip = bwInfo['sessionFilter'][0]['sourceIp']
+        z_ip = bwInfo['sessionFilter'][0]['dstAddress']
+
+        devices = client.ListDevices(Empty()).devices
+        for device in devices:
+            for cr in device.device_config.config_rules:
+                if cr.WhichOneof('config_rule') == 'custom' and cr.custom.resource_key == '_connect/settings':
+                    for ep in json.loads(cr.custom.resource_value)['endpoints']:
+                        if 'ip' in ep and (ep['ip'] == a_ip or ep['ip'] == z_ip):
+                            ep_id = EndPointId()
+                            ep_id.endpoint_uuid.uuid = ep['uuid']
+                            ep_id.device_id.device_uuid.uuid = device.device_id.device_uuid.uuid
+                            service.service_endpoint_ids.append(ep_id)
+        
+        if len(service.service_endpoint_ids) < 2:
+            LOGGER.error('No endpoints matched')
+            return None
+
+    service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
+
+    if 'appInsId' in bwInfo:
+        service.service_id.service_uuid.uuid = bwInfo['appInsId']
+        service.service_id.context_id.context_uuid.uuid = 'admin'
+        service.name = bwInfo['appInsId']
+
+    if 'fixedAllocation' in bwInfo:
+        capacity = Constraint_SLA_Capacity()
+        capacity.capacity_gbps = float(bwInfo['fixedAllocation'])
+        constraint = Constraint()
+        constraint.sla_capacity.CopyFrom(capacity)
+        service.service_constraints.append(constraint)
+
+    return service
+
+
+def format_grpc_to_json(grpc_reply):
+    return jsonify(grpc_message_to_json(grpc_reply))
+
+def grpc_context_id(context_uuid):
+    return ContextId(**json_context_id(context_uuid))
+
+def grpc_service_id(context_uuid, service_uuid):
+    return ServiceId(**json_service_id(service_uuid, context_id=json_context_id(context_uuid)))
diff --git a/src/compute/service/rest_server/nbi_plugins/etsi_bwm/__init__.py b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b81a4057a91891bc86bacd34d157a1a61e14934
--- /dev/null
+++ b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/__init__.py
@@ -0,0 +1,29 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from compute.service.rest_server.RestServer import RestServer
+from .Resources import BwInfo, BwInfoId
+
+URL_PREFIX = '/bwm/v1'
+
+# Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type.
+RESOURCES = [
+    # (endpoint_name, resource_class, resource_url)
+    ('api.bw_info',         BwInfo,     '/bw_allocations'),
+    ('api.bw_info_id',      BwInfoId,   '/bw_allocations/<path:allocationId>'),
+]
+
+def register_etsi_bwm_api(rest_server : RestServer):
+    for endpoint_name, resource_class, resource_url in RESOURCES:
+        rest_server.add_resource(resource_class, URL_PREFIX + resource_url, endpoint=endpoint_name)
diff --git a/src/compute/service/rest_server/nbi_plugins/etsi_bwm/tests_etsi_bwm.txt b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/tests_etsi_bwm.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9cfbe5625de45a044e68a8af8ec8f440423da966
--- /dev/null
+++ b/src/compute/service/rest_server/nbi_plugins/etsi_bwm/tests_etsi_bwm.txt
@@ -0,0 +1,81 @@
+-----------------------GET-----------------------
+
+curl --request GET \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations
+
+
+-----------------------POST-----------------------
+curl --request POST \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations \
+  --header 'Content-Type: application/json' \
+  --data '{
+  "allocationDirection": "string",
+  "appInsId": "service_uuid",
+  "fixedAllocation": "123",
+  "fixedBWPriority": "SEE_DESCRIPTION",
+  "requestType": 0,
+  "sessionFilter": [
+    {
+      "dstAddress": "192.168.3.2",
+      "dstPort": [
+        "b"
+      ],
+      "protocol": "string",
+      "sourceIp": "192.168.1.2",
+      "sourcePort": [
+        "a"
+      ]
+    }
+  ],
+  "timeStamp": {
+    "nanoSeconds": 1,
+    "seconds": 1
+  }
+}'
+
+
+-----------------------GET2-----------------------
+curl --request GET \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations/service_uuid
+
+-----------------------PUT-----------------------
+  curl --request PUT \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations/service_uuid \
+  --header 'Content-Type: application/json' \
+  --data '{
+  "allocationDirection": "string",
+  "appInsId": "service_uuid",
+  "fixedAllocation": "123",
+  "fixedBWPriority": "efefe",
+  "requestType": 0,
+  "sessionFilter": [
+    {
+      "dstAddress": "192.168.3.2",
+      "dstPort": [
+        "b"
+      ],
+      "protocol": "string",
+      "sourceIp": "192.168.1.2",
+      "sourcePort": [
+        "a"
+      ]
+    }
+  ],
+  "timeStamp": {
+    "nanoSeconds": 1,
+    "seconds": 1
+  }
+}'
+
+-----------------------PATCH-----------------------
+curl --request PATCH \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations/service_uuid \
+  --header 'Content-Type: application/json' \
+  --data '{
+  "fixedBWPriority": "uuuuuuuuuuuuuu"
+}'
+
+
+-----------------------DELETE-----------------------
+curl --request DELETE \
+  --url http://10.1.7.203:80/restconf/bwm/v1/bw_allocations/service_uuid
\ No newline at end of file