diff --git a/main.go b/main.go
index 14c100a854400c9cfad03a62f9b5984449fd625c..7822849a322170b0f4546c8e7b1fdfd6f20b9963 100644
--- a/main.go
+++ b/main.go
@@ -19,10 +19,13 @@ import (
 	"github.com/iotaledger/goshimmer/plugins/tipselection"
 	"github.com/iotaledger/goshimmer/plugins/ui"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
-	webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi-gtta"
-	webapi_send_data "github.com/iotaledger/goshimmer/plugins/webapi-send-data"
-	webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi-spammer"
-	webapi_tx_request "github.com/iotaledger/goshimmer/plugins/webapi-tx-request"
+	webapi_broadcastData "github.com/iotaledger/goshimmer/plugins/webapi/broadcastData"
+	webapi_findTransactions "github.com/iotaledger/goshimmer/plugins/webapi/findTransactions"
+	webapi_getNeighbors "github.com/iotaledger/goshimmer/plugins/webapi/getNeighbors"
+	webapi_getTransactions "github.com/iotaledger/goshimmer/plugins/webapi/getTransactions"
+	webapi_getTrytes "github.com/iotaledger/goshimmer/plugins/webapi/getTrytes"
+	webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi/gtta"
+	webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer"
 	"github.com/iotaledger/goshimmer/plugins/webauth"
 	"github.com/iotaledger/goshimmer/plugins/zeromq"
 	"github.com/iotaledger/hive.go/node"
@@ -53,9 +56,11 @@ func main() {
 			webapi.PLUGIN,
 			webapi_gtta.PLUGIN,
 			webapi_spammer.PLUGIN,
-			webapi_send_data.PLUGIN,
-			webapi_tx_request.PLUGIN,
-			webapi_spammer.PLUGIN,
+			webapi_broadcastData.PLUGIN,
+			webapi_getTrytes.PLUGIN,
+			webapi_getTransactions.PLUGIN,
+			webapi_findTransactions.PLUGIN,
+			webapi_getNeighbors.PLUGIN,
 
 			ui.PLUGIN,
 			webauth.PLUGIN,
diff --git a/packages/model/value_transaction/constants.go b/packages/model/value_transaction/constants.go
index c602d1ea6d3870cbc17160914f63c6af1f234eca..06a4c749b4b9ae08c8a030dcedb095c4bb6edb8a 100644
--- a/packages/model/value_transaction/constants.go
+++ b/packages/model/value_transaction/constants.go
@@ -10,7 +10,7 @@ const (
 	ADDRESS_OFFSET                    = 0
 	VALUE_OFFSET                      = ADDRESS_END
 	TIMESTAMP_OFFSET                  = VALUE_END
-	SIGNATURE_MESSAGE_FRAGMENT_OFFSET = TIMESTAMP_SIZE
+	SIGNATURE_MESSAGE_FRAGMENT_OFFSET = TIMESTAMP_END
 
 	ADDRESS_SIZE                    = 243
 	VALUE_SIZE                      = 81
diff --git a/plugins/autopeering/autopeering.go b/plugins/autopeering/autopeering.go
index 474fe2bd3f82d140b4ac9eecab4e09faeaffc966..95b2b8e48f88ee268f3dcf39bf095c7a1cca1677 100644
--- a/plugins/autopeering/autopeering.go
+++ b/plugins/autopeering/autopeering.go
@@ -100,6 +100,7 @@ func start(shutdownSignal <-chan struct{}) {
 	}
 
 	log.Infof("Auto Peering started: address=%s", srv.LocalAddr())
+	log.Debugf("Auto Peering server started: PubKey=%s", base64.StdEncoding.EncodeToString(local.GetInstance().PublicKey()))
 
 	<-shutdownSignal
 	log.Info("Stopping Auto Peering server ...")
diff --git a/plugins/tangle/tx_per_address.go b/plugins/tangle/tx_per_address.go
index c344aeda6028d238a1705f2adcfc169c324f2f09..c6bb03cdce9c63b63a0d388483b8dd2430b85b48 100644
--- a/plugins/tangle/tx_per_address.go
+++ b/plugins/tangle/tx_per_address.go
@@ -30,7 +30,6 @@ func StoreTransactionHashForAddressInDatabase(address *TxHashForAddress) error {
 	); err != nil {
 		return ErrDatabaseError.Derive(err, "failed to store tx for address in database")
 	}
-
 	return nil
 }
 
diff --git a/plugins/ui/ui.go b/plugins/ui/ui.go
index f4458e58434f2c4339da661c6c043f043c4623fd..9d9b8b1cb50a915a1f4ffd838d5a698df7fcf766 100644
--- a/plugins/ui/ui.go
+++ b/plugins/ui/ui.go
@@ -20,18 +20,18 @@ import (
 func configure(plugin *node.Plugin) {
 
 	//webapi.Server.Static("ui", "plugins/ui/src")
-	webapi.AddEndpoint("ui", func(c echo.Context) error {
+	webapi.Server.GET("ui", func(c echo.Context) error {
 		return c.HTML(http.StatusOK, files["index.html"])
 	})
-	webapi.AddEndpoint("ui/**", staticFileServer)
+	webapi.Server.GET("ui/**", staticFileServer)
 
-	webapi.AddEndpoint("ws", upgrader)
-	webapi.AddEndpoint("loghistory", func(c echo.Context) error {
+	webapi.Server.GET("ws", upgrader)
+	webapi.Server.GET("loghistory", func(c echo.Context) error {
 		logMutex.RLock()
 		defer logMutex.RUnlock()
 		return c.JSON(http.StatusOK, logHistory)
 	})
-	webapi.AddEndpoint("tpsqueue", func(c echo.Context) error {
+	webapi.Server.GET("tpsqueue", func(c echo.Context) error {
 		tpsQueueMutex.RLock()
 		defer tpsQueueMutex.RUnlock()
 		return c.JSON(http.StatusOK, tpsQueue)
diff --git a/plugins/webapi-tx-request/plugin.go b/plugins/webapi-tx-request/plugin.go
deleted file mode 100644
index 5f4e4282548acacebab17b8c3b6f4ebd12b4c938..0000000000000000000000000000000000000000
--- a/plugins/webapi-tx-request/plugin.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package webapi_tx_request
-
-import (
-	"net/http"
-	"time"
-
-	"github.com/iotaledger/goshimmer/plugins/tangle"
-	"github.com/iotaledger/goshimmer/plugins/webapi"
-	"github.com/iotaledger/hive.go/logger"
-	"github.com/iotaledger/hive.go/node"
-	"github.com/labstack/echo"
-)
-
-var PLUGIN = node.NewPlugin("WebAPI Transaction Request Endpoint", node.Enabled, configure)
-var log *logger.Logger
-
-func configure(plugin *node.Plugin) {
-	log = logger.NewLogger("API-TxRequest")
-	webapi.AddEndpoint("txRequest", Handler)
-}
-
-func Handler(c echo.Context) error {
-	c.Set("requestStartTime", time.Now())
-
-	var request webRequest
-	if err := c.Bind(&request); err != nil {
-		log.Info(err.Error())
-		return requestFailed(c, err.Error())
-	}
-	log.Info("Received:", request.TransactionHash)
-
-	tx, err := tangle.GetTransaction(request.TransactionHash)
-	if err != nil {
-		return requestFailed(c, err.Error())
-	}
-	if tx == nil {
-		return requestFailed(c, "Tx not found")
-	}
-
-	return requestSuccessful(c, tx.GetBytes())
-}
-
-func requestSuccessful(c echo.Context, tx []byte) error {
-	return c.JSON(http.StatusOK, webResponse{
-		Duration:    time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		Transaction: tx,
-		Status:      "OK",
-	})
-}
-
-func requestFailed(c echo.Context, message string) error {
-	return c.JSON(http.StatusNotFound, webResponse{
-		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		Status:   message,
-	})
-}
-
-type webResponse struct {
-	Duration    int64  `json:"duration"`
-	Transaction []byte `json:"transaction"`
-	Status      string `json:"status"`
-}
-
-type webRequest struct {
-	TransactionHash string `json:"transactionHash"`
-}
diff --git a/plugins/webapi/api.go b/plugins/webapi/api.go
deleted file mode 100644
index 5c50d71bc463fc56775777fe675a8f8ce1283fab..0000000000000000000000000000000000000000
--- a/plugins/webapi/api.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package webapi
-
-import (
-	"github.com/labstack/echo"
-)
-
-func AddEndpoint(url string, handler func(c echo.Context) error) {
-	Server.GET(url, handler)
-}
diff --git a/plugins/webapi-send-data/plugin.go b/plugins/webapi/broadcastData/plugin.go
similarity index 55%
rename from plugins/webapi-send-data/plugin.go
rename to plugins/webapi/broadcastData/plugin.go
index c7029181b5a0e7aa8b987e53b28bca9dbc6b9461..ef857882701736b374d1e7d24c219af15629a8d3 100644
--- a/plugins/webapi-send-data/plugin.go
+++ b/plugins/webapi/broadcastData/plugin.go
@@ -1,62 +1,74 @@
-package webapi_send_data
+package broadcastData
 
 import (
 	"net/http"
 	"time"
 
-	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
-
 	"github.com/iotaledger/goshimmer/packages/gossip"
 	"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
 	"github.com/iotaledger/goshimmer/packages/model/value_transaction"
+	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/tipselection"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
 	"github.com/iotaledger/hive.go/logger"
 	"github.com/iotaledger/hive.go/node"
+	"github.com/iotaledger/hive.go/typeutils"
+	"github.com/iotaledger/iota.go/address"
 	"github.com/iotaledger/iota.go/trinary"
 	"github.com/labstack/echo"
 )
 
-var PLUGIN = node.NewPlugin("WebAPI SendData Endpoint", node.Enabled, configure)
+var PLUGIN = node.NewPlugin("WebAPI broadcastData Endpoint", node.Enabled, configure)
 var log *logger.Logger
 
 func configure(plugin *node.Plugin) {
-	log = logger.NewLogger("API-sendData")
-	webapi.AddEndpoint("sendData", SendDataHandler)
+	log = logger.NewLogger("API-broadcastData")
+	webapi.Server.POST("broadcastData", broadcastData)
 }
 
-func SendDataHandler(c echo.Context) error {
-	c.Set("requestStartTime", time.Now())
+// broadcastData creates a data (0-value) transaction given an input of bytes and
+// broadcasts it to the node's neighbors. It returns the transaction hash if successful.
+func broadcastData(c echo.Context) error {
 
 	var request webRequest
 	if err := c.Bind(&request); err != nil {
 		log.Info(err.Error())
 		return requestFailed(c, err.Error())
 	}
-	log.Info("Received:", request.Data)
+	log.Debug("Received - address:", request.Address, " data:", request.Data)
 	tx := value_transaction.New()
 	tx.SetHead(true)
 	tx.SetTail(true)
 
-	buffer := make([]byte, 6561)
-	if len(request.Data) > 6561 {
-		return requestFailed(c, "data exceding 6561 byte limit")
+	buffer := make([]byte, 2187)
+	if len(request.Data) > 2187 {
+		log.Warn("Data exceeding 2187 byte limit -", len(request.Data))
+		return requestFailed(c, "Data exceeding 2187 byte limit")
 	}
 
-	copy(buffer, []byte(request.Data))
+	copy(buffer, typeutils.StringToBytes(request.Data))
 
 	trytes, err := trinary.BytesToTrytes(buffer)
 	if err != nil {
-		log.Info("Trytes conversion", err.Error())
+		log.Warn("Trytes conversion failed", err.Error())
+		return requestFailed(c, err.Error())
+	}
+
+	err = address.ValidAddress(request.Address)
+	if err != nil {
+		log.Warn("Invalid Address:", request.Address)
 		return requestFailed(c, err.Error())
 	}
 
+	tx.SetAddress(request.Address)
 	tx.SetSignatureMessageFragment(trytes)
+	tx.SetValue(0)
 	tx.SetBranchTransactionHash(tipselection.GetRandomTip())
 	tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
 	tx.SetTimestamp(uint(time.Now().Unix()))
 	if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil {
 		log.Warn("PoW failed", err)
+		return requestFailed(c, err.Error())
 	}
 
 	gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: tx.GetBytes(), Peer: &local.GetInstance().Peer})
@@ -65,25 +77,22 @@ func SendDataHandler(c echo.Context) error {
 
 func requestSuccessful(c echo.Context, txHash string) error {
 	return c.JSON(http.StatusCreated, webResponse{
-		Duration:        time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		TransactionHash: txHash,
-		Status:          "OK",
+		Hash: txHash,
 	})
 }
 
 func requestFailed(c echo.Context, message string) error {
-	return c.JSON(http.StatusNotModified, webResponse{
-		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		Status:   message,
+	return c.JSON(http.StatusBadRequest, webResponse{
+		Error: message,
 	})
 }
 
 type webResponse struct {
-	Duration        int64  `json:"duration"`
-	TransactionHash string `json:"transactionHash"`
-	Status          string `json:"status"`
+	Hash  string `json:"hash,omitempty"`
+	Error string `json:"error,omitempty"`
 }
 
 type webRequest struct {
-	Data string `json:"data"`
+	Address string `json:"address"`
+	Data    string `json:"data"`
 }
diff --git a/plugins/webapi/findTransactions/plugin.go b/plugins/webapi/findTransactions/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..cf0f12397c93f773eb89f7a64c6a561824e38a0f
--- /dev/null
+++ b/plugins/webapi/findTransactions/plugin.go
@@ -0,0 +1,67 @@
+package findTransactions
+
+import (
+	"net/http"
+
+	"github.com/iotaledger/goshimmer/plugins/tangle"
+	"github.com/iotaledger/goshimmer/plugins/webapi"
+	"github.com/iotaledger/hive.go/logger"
+	"github.com/iotaledger/hive.go/node"
+	"github.com/iotaledger/iota.go/trinary"
+	"github.com/labstack/echo"
+)
+
+var PLUGIN = node.NewPlugin("WebAPI findTransactions Endpoint", node.Enabled, configure)
+var log *logger.Logger
+
+func configure(plugin *node.Plugin) {
+	log = logger.NewLogger("API-findTransactions")
+	webapi.Server.GET("findTransactions", findTransactions)
+}
+
+// findTransactions returns the array of transaction hashes for the
+// given addresses (in the same order as the parameters).
+// If a node doesn't have any transaction hash for a given address in its ledger,
+// the value at the index of that address is empty.
+func findTransactions(c echo.Context) error {
+
+	var request webRequest
+
+	if err := c.Bind(&request); err != nil {
+		log.Info(err.Error())
+		return requestFailed(c, err.Error())
+	}
+	log.Debug("Received:", request.Addresses)
+	result := make([][]trinary.Trytes, len(request.Addresses))
+
+	for i, address := range request.Addresses {
+		txs, err := tangle.ReadTransactionHashesForAddressFromDatabase(address)
+		if err != nil {
+			return requestFailed(c, err.Error())
+		}
+		result[i] = append(result[i], txs...)
+	}
+
+	return requestSuccessful(c, result)
+}
+
+func requestSuccessful(c echo.Context, txHashes [][]trinary.Trytes) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Transactions: txHashes,
+	})
+}
+
+func requestFailed(c echo.Context, message string) error {
+	return c.JSON(http.StatusNotFound, webResponse{
+		Error: message,
+	})
+}
+
+type webResponse struct {
+	Transactions [][]trinary.Trytes `json:"transactions,omitempty"` //string
+	Error        string             `json:"error,omitempty"`
+}
+
+type webRequest struct {
+	Addresses []string `json:"addresses"`
+}
diff --git a/plugins/webapi/getNeighbors/plugin.go b/plugins/webapi/getNeighbors/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..01457705fc37079d7c4580dd83e4d41e32612b81
--- /dev/null
+++ b/plugins/webapi/getNeighbors/plugin.go
@@ -0,0 +1,112 @@
+package getNeighbors
+
+import (
+	"encoding/base64"
+	"net/http"
+
+	"github.com/iotaledger/goshimmer/packages/autopeering/peer"
+	"github.com/iotaledger/goshimmer/packages/autopeering/peer/service"
+	"github.com/iotaledger/goshimmer/plugins/autopeering"
+	"github.com/iotaledger/goshimmer/plugins/webapi"
+	"github.com/iotaledger/hive.go/logger"
+	"github.com/iotaledger/hive.go/node"
+	"github.com/labstack/echo"
+)
+
+var PLUGIN = node.NewPlugin("WebAPI getNeighbors Endpoint", node.Enabled, configure)
+var log *logger.Logger
+
+func configure(plugin *node.Plugin) {
+	log = logger.NewLogger("API-getNeighbors")
+	webapi.Server.GET("getNeighbors", getNeighbors)
+}
+
+// getNeighbors returns the chosen and accepted neighbors of the node
+func getNeighbors(c echo.Context) error {
+
+	chosen := []neighbor{}
+	accepted := []neighbor{}
+
+	if autopeering.Selection == nil {
+		return requestFailed(c, "Neighbor Selection is not enabled")
+	}
+
+	for _, peer := range autopeering.Selection.GetOutgoingNeighbors() {
+
+		n := neighbor{
+			ID:        peer.ID().String(),
+			PublicKey: base64.StdEncoding.EncodeToString(peer.PublicKey()),
+		}
+		n.Services = getServices(peer)
+		chosen = append(chosen, n)
+	}
+	for _, peer := range autopeering.Selection.GetIncomingNeighbors() {
+		n := neighbor{
+			ID:        peer.ID().String(),
+			PublicKey: base64.StdEncoding.EncodeToString(peer.PublicKey()),
+		}
+		n.Services = getServices(peer)
+		accepted = append(accepted, n)
+	}
+	return requestSuccessful(c, chosen, accepted)
+
+}
+
+func requestSuccessful(c echo.Context, chosen, accepted []neighbor) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Chosen:   chosen,
+		Accepted: accepted,
+	})
+}
+
+func requestFailed(c echo.Context, message string) error {
+	return c.JSON(http.StatusNotFound, webResponse{
+		Error: message,
+	})
+}
+
+type webResponse struct {
+	Chosen   []neighbor `json:"chosen"`
+	Accepted []neighbor `json:"accepted"`
+	Error    string     `json:"error,omitempty"`
+}
+
+type neighbor struct {
+	ID        string `json:"id"`        // comparable node identifier
+	PublicKey string `json:"publicKey"` // public key used to verify signatures
+	Services  []peerService
+}
+
+type peerService struct {
+	ID      string `json:"id"`      // ID of the service
+	Address string `json:"address"` // network address of the service
+}
+
+func getServices(p *peer.Peer) []peerService {
+	services := []peerService{}
+	peeringService := p.Services().Get(service.PeeringKey)
+	if peeringService != nil {
+		services = append(services, peerService{
+			ID:      "peering",
+			Address: peeringService.String(),
+		})
+	}
+
+	gossipService := p.Services().Get(service.GossipKey)
+	if gossipService != nil {
+		services = append(services, peerService{
+			ID:      "gossip",
+			Address: gossipService.String(),
+		})
+	}
+
+	fpcService := p.Services().Get(service.FPCKey)
+	if fpcService != nil {
+		services = append(services, peerService{
+			ID:      "FPC",
+			Address: fpcService.String(),
+		})
+	}
+
+	return services
+}
diff --git a/plugins/webapi/getTransactions/plugin.go b/plugins/webapi/getTransactions/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..2dfb696f2deba6bb5843dd0ef185a49f9da66ecb
--- /dev/null
+++ b/plugins/webapi/getTransactions/plugin.go
@@ -0,0 +1,100 @@
+package getTransactions
+
+import (
+	"net/http"
+
+	"github.com/iotaledger/goshimmer/plugins/tangle"
+	"github.com/iotaledger/goshimmer/plugins/webapi"
+	"github.com/iotaledger/hive.go/logger"
+	"github.com/iotaledger/hive.go/node"
+	"github.com/iotaledger/iota.go/trinary"
+	"github.com/labstack/echo"
+)
+
+var PLUGIN = node.NewPlugin("WebAPI getTransaction Endpoint", node.Enabled, configure)
+var log *logger.Logger
+
+func configure(plugin *node.Plugin) {
+	log = logger.NewLogger("API-getTransactions")
+	webapi.Server.GET("getTransactions", getTransactions)
+}
+
+// getTransactions returns the array of transactions for the
+// given transaction hashes (in the same order as the parameters).
+// If a node doesn't have the transaction for a given transaction hash in its ledger,
+// the value at the index of that transaction hash is empty.
+func getTransactions(c echo.Context) error {
+
+	var request webRequest
+	result := []transaction{}
+
+	if err := c.Bind(&request); err != nil {
+		log.Info(err.Error())
+		return requestFailed(c, err.Error())
+	}
+	log.Debug("Received:", request.Hashes)
+
+	for _, hash := range request.Hashes {
+		tx, err := tangle.GetTransaction(hash)
+		if err != nil {
+			return requestFailed(c, err.Error())
+		}
+		if tx != nil {
+			t := transaction{
+				Hash:                     tx.GetHash(),
+				WeightMagnitude:          tx.GetWeightMagnitude(),
+				TrunkTransactionHash:     tx.GetTrunkTransactionHash(),
+				BranchTransactionHash:    tx.GetBranchTransactionHash(),
+				Head:                     tx.IsHead(),
+				Tail:                     tx.IsTail(),
+				Nonce:                    tx.GetNonce(),
+				Address:                  tx.GetAddress(),
+				Value:                    tx.GetValue(),
+				Timestamp:                tx.GetTimestamp(),
+				SignatureMessageFragment: tx.GetSignatureMessageFragment(),
+			}
+			result = append(result, t)
+		} else {
+			//tx not found
+			result = append(result, transaction{})
+		}
+
+	}
+
+	return requestSuccessful(c, result)
+}
+
+func requestSuccessful(c echo.Context, txs []transaction) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Transactions: txs,
+	})
+}
+
+func requestFailed(c echo.Context, message string) error {
+	return c.JSON(http.StatusNotFound, webResponse{
+		Error: message,
+	})
+}
+
+type webResponse struct {
+	Transactions []transaction `json:"transaction,omitempty"`
+	Error        string        `json:"error,omitempty"`
+}
+
+type webRequest struct {
+	Hashes []string `json:"hashes"`
+}
+
+type transaction struct {
+	Hash                     trinary.Trytes `json:"hash,omitempty"`
+	WeightMagnitude          int            `json:"weightMagnitude,omitempty"`
+	TrunkTransactionHash     trinary.Trytes `json:"trunkTransactionHash,omitempty"`
+	BranchTransactionHash    trinary.Trytes `json:"branchTransactionHash,omitempty"`
+	Head                     bool           `json:"head,omitempty"`
+	Tail                     bool           `json:"tail,omitempty"`
+	Nonce                    trinary.Trytes `json:"nonce,omitempty"`
+	Address                  trinary.Trytes `json:"address,omitempty"`
+	Value                    int64          `json:"value,omitempty"`
+	Timestamp                uint           `json:"timestamp,omitempty"`
+	SignatureMessageFragment trinary.Trytes `json:"signatureMessageFragment,omitempty"`
+}
diff --git a/plugins/webapi/getTrytes/plugin.go b/plugins/webapi/getTrytes/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..4dac6f1b9730039b862a77d60924cab1f226a13e
--- /dev/null
+++ b/plugins/webapi/getTrytes/plugin.go
@@ -0,0 +1,77 @@
+package getTrytes
+
+import (
+	"net/http"
+
+	"github.com/iotaledger/goshimmer/plugins/tangle"
+	"github.com/iotaledger/goshimmer/plugins/webapi"
+	"github.com/iotaledger/hive.go/logger"
+	"github.com/iotaledger/hive.go/node"
+	"github.com/iotaledger/iota.go/trinary"
+	"github.com/labstack/echo"
+)
+
+var PLUGIN = node.NewPlugin("WebAPI getTrytes Endpoint", node.Enabled, configure)
+var log *logger.Logger
+
+func configure(plugin *node.Plugin) {
+	log = logger.NewLogger("API-getTrytes")
+	webapi.Server.GET("getTrytes", getTrytes)
+}
+
+// getTrytes returns the array of transaction trytes for the
+// given transaction hashes (in the same order as the parameters).
+// If a node doesn't have the trytes for a given transaction hash in its ledger,
+// the value at the index of that transaction hash is empty.
+func getTrytes(c echo.Context) error {
+
+	var request webRequest
+	result := []trinary.Trytes{}
+	if err := c.Bind(&request); err != nil {
+		log.Info(err.Error())
+		return requestFailed(c, err.Error())
+	}
+	log.Debug("Received:", request.Hashes)
+
+	for _, hash := range request.Hashes {
+		tx, err := tangle.GetTransaction(hash)
+		if err != nil {
+			return requestFailed(c, err.Error())
+		}
+		if tx != nil {
+			trytes, err := trinary.TritsToTrytes(tx.GetTrits())
+			// Returns an error if len(tx.GetTrits())%3!=0
+			if err != nil {
+				return requestFailed(c, err.Error())
+			}
+			result = append(result, trytes)
+		} else {
+			//tx not found
+			result = append(result, "")
+		}
+
+	}
+
+	return requestSuccessful(c, result)
+}
+
+func requestSuccessful(c echo.Context, txTrytes []trinary.Trytes) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Trytes: txTrytes,
+	})
+}
+
+func requestFailed(c echo.Context, message string) error {
+	return c.JSON(http.StatusNotFound, webResponse{
+		Error: message,
+	})
+}
+
+type webResponse struct {
+	Trytes []trinary.Trytes `json:"trytes,omitempty"` //string
+	Error  string           `json:"error,omitempty"`
+}
+
+type webRequest struct {
+	Hashes []string `json:"hashes"`
+}
diff --git a/plugins/webapi-gtta/plugin.go b/plugins/webapi/gtta/plugin.go
similarity index 68%
rename from plugins/webapi-gtta/plugin.go
rename to plugins/webapi/gtta/plugin.go
index c873f7a4024752229e8ae96be61f0b9e7fc515d3..3234ddc61d83583bcad22988d29b7c8ec5b424ec 100644
--- a/plugins/webapi-gtta/plugin.go
+++ b/plugins/webapi/gtta/plugin.go
@@ -1,8 +1,7 @@
-package webapi_gtta
+package gtta
 
 import (
 	"net/http"
-	"time"
 
 	"github.com/iotaledger/goshimmer/plugins/tipselection"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
@@ -11,25 +10,22 @@ import (
 	"github.com/labstack/echo"
 )
 
-var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Enabled, func(plugin *node.Plugin) {
-	webapi.AddEndpoint("getTransactionsToApprove", Handler)
+var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin *node.Plugin) {
+	webapi.Server.GET("getTransactionsToApprove", Handler)
 })
 
 func Handler(c echo.Context) error {
-	start := time.Now()
 
 	branchTransactionHash := tipselection.GetRandomTip()
 	trunkTransactionHash := tipselection.GetRandomTip()
 
 	return c.JSON(http.StatusOK, webResponse{
-		Duration:          time.Since(start).Nanoseconds() / 1e6,
 		BranchTransaction: branchTransactionHash,
 		TrunkTransaction:  trunkTransactionHash,
 	})
 }
 
 type webResponse struct {
-	Duration          int64          `json:"duration"`
 	BranchTransaction trinary.Trytes `json:"branchTransaction"`
 	TrunkTransaction  trinary.Trytes `json:"trunkTransaction"`
 }
diff --git a/plugins/webapi-spammer/plugin.go b/plugins/webapi/spammer/plugin.go
similarity index 67%
rename from plugins/webapi-spammer/plugin.go
rename to plugins/webapi/spammer/plugin.go
index fb169eb86b2b281be9646b312c1208e5d767ae4d..fe29875dad56ea89b4153987bd43c94e2f086bc7 100644
--- a/plugins/webapi-spammer/plugin.go
+++ b/plugins/webapi/spammer/plugin.go
@@ -1,8 +1,7 @@
-package webapi_spammer
+package spammer
 
 import (
 	"net/http"
-	"time"
 
 	"github.com/iotaledger/goshimmer/packages/transactionspammer"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
@@ -13,11 +12,10 @@ import (
 var PLUGIN = node.NewPlugin("Spammer", node.Disabled, configure)
 
 func configure(plugin *node.Plugin) {
-	webapi.AddEndpoint("spammer", WebApiHandler)
+	webapi.Server.GET("spammer", WebApiHandler)
 }
 
 func WebApiHandler(c echo.Context) error {
-	c.Set("requestStartTime", time.Now())
 
 	var request webRequest
 	if err := c.Bind(&request); err != nil {
@@ -27,7 +25,7 @@ func WebApiHandler(c echo.Context) error {
 	switch request.Cmd {
 	case "start":
 		if request.Tps == 0 {
-			request.Tps = 1000
+			request.Tps = 1
 		}
 
 		transactionspammer.Stop()
@@ -47,24 +45,18 @@ func WebApiHandler(c echo.Context) error {
 
 func requestSuccessful(c echo.Context, message string) error {
 	return c.JSON(http.StatusOK, webResponse{
-		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		Status:   "success",
-		Message:  message,
+		Message: message,
 	})
 }
 
 func requestFailed(c echo.Context, message string) error {
-	return c.JSON(http.StatusOK, webResponse{
-		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
-		Status:   "failed",
-		Message:  message,
+	return c.JSON(http.StatusNotFound, webResponse{
+		Message: message,
 	})
 }
 
 type webResponse struct {
-	Duration int64  `json:"duration"`
-	Status   string `json:"status"`
-	Message  string `json:"message"`
+	Message string `json:"message"`
 }
 
 type webRequest struct {
diff --git a/plugins/webauth/webauth.go b/plugins/webauth/webauth.go
index b2c898a873f26e9fcc87c7effe5b426c4cb914ff..2b9048781ff915a8269f8a081a735f3270de3769 100644
--- a/plugins/webauth/webauth.go
+++ b/plugins/webauth/webauth.go
@@ -41,7 +41,7 @@ func configure(plugin *node.Plugin) {
 
 func run(plugin *node.Plugin) {
 	daemon.BackgroundWorker("webauth", func(shutdownSignal <-chan struct{}) {
-		webapi.AddEndpoint("login", func(c echo.Context) error {
+		webapi.Server.GET("login", func(c echo.Context) error {
 			username := c.FormValue("username")
 			password := c.FormValue("password")
 			uiUser := os.Getenv("UI_USER")