diff --git a/controller/api/device.go b/controller/api/device.go
index 3ee5e7f2115be68b6f212254e0e6d8cc26ff2d49..b18ed039621931d87a1cbd1a9beed8edf9a7974a 100644
--- a/controller/api/device.go
+++ b/controller/api/device.go
@@ -127,7 +127,7 @@ func GetFlattenedDevices(ctx context.Context, addr, pid string) (*ppb.GetFlatten
 		return nil, err
 	}
 
-	req := &ppb.GetFlattenedOndListRequest{
+	req := &ppb.GetOndListRequest{
 		Timestamp: time.Now().UnixNano(),
 		Pid:       pid,
 	}
diff --git a/controller/interfaces/device/device.go b/controller/interfaces/device/device.go
index fa424fd5599677945503e3d4d5244b2767b1147b..da6c76716cf05df5940216f99c59551273a28142 100644
--- a/controller/interfaces/device/device.go
+++ b/controller/interfaces/device/device.go
@@ -51,4 +51,14 @@ type LoadedDevice struct {
 	// SBI indicates the southbound interface, which is used by this device as UUID.
 	SBI   string `json:"sbi"`
 	Model string `json:"model,omitempty" bson:"model,omitempty"`
+
+	convertFunc func(LoadedDevice) (Device, error)
+}
+
+func (ld LoadedDevice) SetConvertFunction(cf func(LoadedDevice) (Device, error)) {
+	ld.convertFunc = cf
+}
+
+func (ld LoadedDevice) ConvertToDevice() (Device, error) {
+	return ld.convertFunc(ld)
 }
diff --git a/controller/northbound/server/device.go b/controller/northbound/server/device.go
index e034192fd4d391a26e11e9d438edbbea7d6a183a..c5c07936af54bfa0744ba0dd37854e9682161426 100644
--- a/controller/northbound/server/device.go
+++ b/controller/northbound/server/device.go
@@ -54,6 +54,10 @@ func (d *DeviceServer) GetAll(ctx context.Context, request *dpb.GetAllDeviceRequ
 
 	onds := []*dpb.Device{}
 	for _, device := range devices {
+		device, err := device.ConvertToDevice()
+		if err != nil {
+			return nil, status.Errorf(codes.Aborted, "%v", err)
+		}
 		ygotStructAsJSON, err := device.GetModelAsString()
 		if err != nil {
 			log.Error(err)
diff --git a/controller/northbound/server/pnd.go b/controller/northbound/server/pnd.go
index a4a0557073a0bfc53eaf9ec4bab449ff903e1d55..c0dc0367df4bfbc86129db3ec91dd39e63c0a104 100644
--- a/controller/northbound/server/pnd.go
+++ b/controller/northbound/server/pnd.go
@@ -75,8 +75,49 @@ func (p PndServer) GetOnd(ctx context.Context, request *ppb.GetOndRequest) (*ppb
 	}, nil
 }
 
+// GetOndList returns a list of existing onds
+func (p PndServer) GetOndList(ctx context.Context, request *ppb.GetOndListRequest) (*ppb.GetOndListResponse, error) {
+	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
+	start := metrics.StartHook(labels, grpcRequestsTotal)
+	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
+	pid, err := uuid.Parse(request.Pid)
+	if err != nil {
+		return nil, handleRPCError(labels, err)
+	}
+
+	pnd, err := p.pndStore.Get(store.Query{ID: pid})
+	if err != nil {
+		log.Error(err)
+		return nil, status.Errorf(codes.Aborted, "%v", err)
+	}
+
+	onds := make([]*ppb.OrchestratedNetworkingDevice, len(pnd.Devices()))
+	for i, loadedDevice := range pnd.Devices() {
+		device, err := loadedDevice.ConvertToDevice()
+		if err != nil {
+			return nil, status.Errorf(codes.Aborted, "%v", err)
+		}
+		ond, err := fillOndBySpecificPath(pnd, device, "/")
+		if err != nil {
+			log.Error(err)
+			return nil, status.Errorf(codes.Aborted, "%v", err)
+		}
+		onds[i] = ond
+	}
+
+	return &ppb.GetOndListResponse{
+		Timestamp: time.Now().UnixNano(),
+		Pnd: &ppb.PrincipalNetworkDomain{
+			Id:          pnd.ID().String(),
+			Name:        pnd.GetName(),
+			Description: pnd.GetDescription(),
+		},
+		Ond: onds,
+	}, nil
+}
+
 // GetFlattenedOndList returns a list of existing onds
-func (p PndServer) GetFlattenedOndList(ctx context.Context, request *ppb.GetFlattenedOndListRequest) (*ppb.GetFlattenedOndListResponse, error) {
+func (p PndServer) GetFlattenedOndList(ctx context.Context, request *ppb.GetOndListRequest) (*ppb.GetFlattenedOndListResponse, error) {
 	labels := prometheus.Labels{"service": "pnd", "rpc": "get"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
diff --git a/controller/nucleus/deviceService.go b/controller/nucleus/deviceService.go
index 8fc832830aeb16d16144c4e339b641d129d58a25..55338bbbbd93c3563d99f2a2065bff3252ae06f6 100644
--- a/controller/nucleus/deviceService.go
+++ b/controller/nucleus/deviceService.go
@@ -48,6 +48,8 @@ func (s *DeviceService) Get(query store.Query) (device.Device, error) {
 		return nil, err
 	}
 
+	loadedDevice.SetConvertFunction(s.createDeviceFromStore)
+
 	device, err := s.createDeviceFromStore(loadedDevice)
 	if err != nil {
 		return nil, err
@@ -63,6 +65,10 @@ func (s *DeviceService) GetAll() ([]device.LoadedDevice, error) {
 		return nil, err
 	}
 
+	for _, loadedDevice := range loadedDevices {
+		loadedDevice.SetConvertFunction(s.createDeviceFromStore)
+	}
+
 	return loadedDevices, nil
 }
 
diff --git a/controller/nucleus/deviceWatcher.go b/controller/nucleus/deviceWatcher.go
index de7f135afb62ca2fab0f69d823985acd3e246b38..24eb8eaad0bc75cdd58aaceddf3d2941af221b0f 100644
--- a/controller/nucleus/deviceWatcher.go
+++ b/controller/nucleus/deviceWatcher.go
@@ -68,7 +68,8 @@ func (d *DeviceWatcher) SubToDevices(paths [][]string, opts *gnmi.SubscribeOptio
 }
 
 func (d *DeviceWatcher) subscribeToPndDevices(pndID string, pnd networkdomain.NetworkDomain, opts *gnmi.SubscribeOptions) {
-	for _, device := range pnd.Devices() {
+	for _, loadedDevice := range pnd.Devices() {
+		device, _ := loadedDevice.ConvertToDevice()
 		subID := uuid.New()
 
 		stopContext, cancel := context.WithCancel(context.Background())