diff --git a/consensus/clique/api.go b/consensus/clique/api.go
index 6bcf987af55eb983a1dad6c6f9da8909eea7054b..fdb7b7a07904ad82995f058e3160be1a8fb9ca8d 100644
--- a/consensus/clique/api.go
+++ b/consensus/clique/api.go
@@ -17,6 +17,8 @@
 package clique
 
 import (
+	"fmt"
+
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/consensus"
 	"github.com/ethereum/go-ethereum/core/types"
@@ -117,3 +119,59 @@ func (api *API) Discard(address common.Address) {
 
 	delete(api.clique.proposals, address)
 }
+
+type Status struct {
+	InturnPercent float64                `json:"inturnPercent"`
+	SigningStatus map[common.Address]int `json:"sealerActivity""`
+	NumBlocks     uint64                 `json:"numBlocks"`
+}
+
+// Status returns the status of the last N blocks,
+// - the number of active signers,
+// - the number of signers,
+// - the percentage of in-turn blocks
+func (api *API) Status() (*Status, error) {
+	var (
+		numBlocks = uint64(64)
+		header    = api.chain.CurrentHeader()
+		diff      = uint64(0)
+		optimals  = 0
+	)
+	snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
+	if err != nil {
+		return nil, err
+	}
+	var (
+		signers = snap.signers()
+		end     = header.Number.Uint64()
+		start   = end - numBlocks
+	)
+	if numBlocks > end {
+		start = 1
+		numBlocks = end - start
+	}
+	signStatus := make(map[common.Address]int)
+	for _, s := range signers {
+		signStatus[s] = 0
+	}
+	for n := start; n < end; n++ {
+		h := api.chain.GetHeaderByNumber(n)
+		if h == nil {
+			return nil, fmt.Errorf("missing block %d", n)
+		}
+		if h.Difficulty.Cmp(diffInTurn) == 0 {
+			optimals++
+		}
+		diff += h.Difficulty.Uint64()
+		sealer, err := api.clique.Author(h)
+		if err != nil {
+			return nil, err
+		}
+		signStatus[sealer]++
+	}
+	return &Status{
+		InturnPercent: float64((100 * optimals)) / float64(numBlocks),
+		SigningStatus: signStatus,
+		NumBlocks:     numBlocks,
+	}, nil
+}