diff --git a/lightmotif-py/lightmotif/lib.pyi b/lightmotif-py/lightmotif/lib.pyi
index 91cd2e3228a0c4987fb14990a69d7a7b953047ba..059b291bf90129490902784b0cefb785e1d9c787 100644
--- a/lightmotif-py/lightmotif/lib.pyi
+++ b/lightmotif-py/lightmotif/lib.pyi
@@ -20,12 +20,16 @@ class EncodedSequence:
     def __len__(self) -> int: ...
     def __copy__(self) -> EncodedSequence: ...
     def __buffer__(self, flags: int) -> memoryview: ...
+    @property
+    def protein(self) -> bool: ...
     def copy(self) -> EncodedSequence: ...
     def stripe(self) -> StripedSequence: ...
 
 class StripedSequence:
     def __copy__(self) -> StripedSequence: ...
     def __buffer__(self, flags: int) -> memoryview: ...
+    @property
+    def protein(self) -> bool: ...
     def copy(self) -> StripedSequence: ...
 
 class CountMatrix:
@@ -35,6 +39,8 @@ class CountMatrix:
     def __eq__(self, other: object) -> bool: ...
     def __len__(self) -> int: ...
     def __getitem__(self, index: int) -> List[int]: ...
+    @property
+    def protein(self) -> bool: ...
     def normalize(
         self, pseudocount: Union[None, float, Dict[str, float]] = None
     ) -> WeightMatrix: ...
@@ -43,6 +49,8 @@ class WeightMatrix:
     def __eq__(self, other: object) -> bool: ...
     def __len__(self) -> int: ...
     def __getitem__(self, index: int) -> List[int]: ...
+    @property
+    def protein(self) -> bool: ...
     def log_odds(
         self, background: Union[None, Dict[str, float]] = None, base: float = 2.0
     ) -> ScoringMatrix: ...
@@ -54,6 +62,8 @@ class ScoringMatrix:
     def __len__(self) -> int: ...
     def __eq__(self, other: object) -> bool: ...
     def __buffer__(self, flags: int) -> memoryview: ...
+    @property
+    def protein(self) -> bool: ...
     def calculate(self, sequence: StripedSequence) -> StripedScores: ...
     def pvalue(self, score: float) -> float: ...
     def score(self, pvalue: float) -> float: ...
@@ -76,6 +86,8 @@ class Motif:
     def pssm(self) -> ScoringMatrix: ...
     @property
     def name(self) -> Optional[str]: ...
+    @property
+    def protein(self) -> bool: ...
 
 class TransfacMotif(Motif):
     @property
diff --git a/lightmotif-py/lightmotif/lib.rs b/lightmotif-py/lightmotif/lib.rs
index 98b4d190cad0cbbf5714182afc0701abcd0b8074..54453a77655d70b1f391b5f4217db2742e5216b8 100644
--- a/lightmotif-py/lightmotif/lib.rs
+++ b/lightmotif-py/lightmotif/lib.rs
@@ -253,6 +253,12 @@ impl EncodedSequence {
         Ok(())
     }
 
+    /// `bool`: `True` if the encoded sequence is a protein sequence.
+    #[getter]
+    pub fn protein(&self) -> bool {
+        matches!(self.data, EncodedSequenceData::Protein(_))
+    }
+
     /// Create a copy of this sequence.
     pub fn copy(&self) -> Self {
         self.clone()
@@ -331,9 +337,10 @@ impl StripedSequence {
         self.copy()
     }
 
-    /// Create a copy of this sequence.
-    pub fn copy(&self) -> Self {
-        self.clone()
+    /// `bool`: `True` if the striped sequence is a protein sequence.
+    #[getter]
+    pub fn protein(&self) -> bool {
+        matches!(self.data, StripedSequenceData::Protein(_))
     }
 
     unsafe fn __getbuffer__(
@@ -371,6 +378,11 @@ impl StripedSequence {
 
         Ok(())
     }
+
+    /// Create a copy of this sequence.
+    pub fn copy(&self) -> Self {
+        self.clone()
+    }
 }
 
 // --- CountMatrix -------------------------------------------------------------
@@ -489,6 +501,12 @@ impl CountMatrix {
         Ok(row)
     }
 
+    /// `bool`: `True` if the count matrix stores protein counts.
+    #[getter]
+    pub fn protein(&self) -> bool {
+        matches!(self.data, CountMatrixData::Protein(_))
+    }
+
     /// Normalize this count matrix to obtain a position weight matrix.
     ///
     /// This method converts the count matrix to a weight matrix. Each row
@@ -612,6 +630,12 @@ impl WeightMatrix {
         Ok(row)
     }
 
+    /// `bool`: `True` if the weight matrix stores protein weights.
+    #[getter]
+    pub fn protein(&self) -> bool {
+        matches!(self.data, WeightMatrixData::Protein(_))
+    }
+
     /// Log-scale this weight matrix to obtain a position-specific scoring matrix.
     ///
     /// Arguments:
@@ -831,6 +855,12 @@ impl ScoringMatrix {
         Ok(())
     }
 
+    /// `bool`: `True` if the scoring matrix stores protein scores.
+    #[getter]
+    pub fn protein(&self) -> bool {
+        matches!(self.data, ScoringMatrixData::Protein(_))
+    }
+
     /// Calculate the PSSM score for all positions of the given sequence.
     ///
     /// Returns:
@@ -1090,6 +1120,19 @@ impl Motif {
     }
 }
 
+#[pymethods]
+impl Motif {
+    /// `bool`: `True` if the motif is a protein motif.
+    #[getter]
+    pub fn protein<'py>(slf: PyRef<'py, Self>) -> bool {
+        let py = slf.py();
+        matches!(
+            slf.pssm.bind(py).borrow().data,
+            ScoringMatrixData::Protein(_)
+        )
+    }
+}
+
 // --- Scanner -----------------------------------------------------------------
 
 #[pyclass(module = "lightmotif.lib")]