diff --git a/.env b/.env
index d3e5a5dc0afe6abbf0d4624faaa14fb2a3170c1d..480714f3c2fb8c30e696e60a3125e51aae003fdb 100644
--- a/.env
+++ b/.env
@@ -48,3 +48,6 @@ MAILER_FROM=ne-pas-repondre@balex.fr
 ###> nelmio/cors-bundle ###
 CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
 ###< nelmio/cors-bundle ###
+
+###> app ###
+ENTRY_APPROVAL_NB=7
\ No newline at end of file
diff --git a/src/Controller/ApiEntryController.php b/src/Controller/ApiEntryController.php
index 71f78c893b80b4b6f15d79b5f0d1e67a8edde0c1..ca6d8383d281719460ea25e727fa8fed4ea18008 100644
--- a/src/Controller/ApiEntryController.php
+++ b/src/Controller/ApiEntryController.php
@@ -185,7 +185,7 @@ class ApiEntryController extends ApiBaseController
     }
 
     /**
-     * Copie une sélection d'entrée vers des lexiques cibles. Si force=true, on crée l'entrée même si le mot n'est pas trouvé dans le wiktionnaire
+     * Copie une sélection d'entrée vers des lexiques cibles.
      *
      * @Route("/copy", name="api_copy_entries", methods={"POST"})
      *
@@ -548,4 +548,39 @@ class ApiEntryController extends ApiBaseController
 
         return $this->createJsonResponse(200, ['success' => sprintf("Entrée %s supprimée du lexique %s", $entry, $data['target_lex'])]);
     }
+
+    /**
+     * @Route("/add-approval/{id}", name="api_entry_add_approval", methods={"PUT"})
+     *
+     * @OA\Response(response=200, description="success", @OA\JsonContent(type="string"))
+     * @OA\Response(response=401, description="error", @OA\JsonContent(type="string"))
+     * @OA\Response(response=403, description="error", @OA\JsonContent(type="string"))
+     * @OA\Response(response=500, description="error", @OA\JsonContent(type="string"))
+     *
+     * @OA\Parameter(
+     *     name="id",
+     *     in="path",
+     *     description="id of the entry to approve",
+     *     @OA\Schema(type="string")
+     * )
+     * @OA\Tag(name="Entries")
+     * @Security(name="OAuth2")
+     */
+    public function addApproval(Request $request, Entry $entry = null)
+    {
+        if ($entry === null) {
+            return $this->createJsonResponse(401, ['error' => sprintf("Pas d'entrée trouvée pour cette Id")]);
+        }
+
+        $entry->addApproval();
+        if ($entry->getLexicon()->isNewWords() && $entry->getApprovalNb() >= $_ENV['ENTRY_APPROVAL_NB']) {
+            // TODO merger les entries ou ne rien faire si on a déjà une entry pour ce headword
+            $entry->setLexicon($this->getZeroLexicon($entry->getLanguage()));
+        }
+
+        $this->doctrine->getManager()->flush();
+        $this->addSuccessMessage(sprintf("Approbation ajoutée à l'entrée %s", $entry->getId()));
+
+        return $this->createJsonResponse();
+    }
 }
diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php
index ba7eff971e432dc940042f8b150c925d9f94c0e3..69c985bef650762707e1e42a2212f0ac80d97ebc 100644
--- a/src/Entity/Entry.php
+++ b/src/Entity/Entry.php
@@ -55,6 +55,12 @@ class Entry
      */
     private $language;
 
+    /**
+     * @Groups({"entry:read"})
+     * @ORM\Column(type="integer")
+     */
+    private $approvalNb = 0;
+
     /**
      * @Groups({"entry:read"})
      * @ORM\Column(type="datetime_immutable")
@@ -94,6 +100,11 @@ class Entry
         return $this->getHeadword()->getValue();
     }
 
+    public function addApproval()
+    {
+        $this->setApprovalNb($this->getApprovalNb() + 1);
+    }
+
     public function getFormattedDefinitions()
     {
         $result = [];
@@ -130,6 +141,10 @@ class Entry
 
     public function setAttributes(?array $attributes): self
     {
+        if ($this->getAttributes() != $attributes) {
+            $this->setApprovalNb(0);
+        }
+
         $this->attributes = $attributes;
 
         return $this;
@@ -248,4 +263,16 @@ class Entry
 
         return $this;
     }
+
+    public function getApprovalNb(): ?int
+    {
+        return $this->approvalNb;
+    }
+
+    public function setApprovalNb(int $approvalNb): self
+    {
+        $this->approvalNb = $approvalNb;
+
+        return $this;
+    }
 }