diff --git a/migration/20.10/2010.sql b/migration/20.10/2010.sql
index 25a266f54d84eb9d6437ec0dc21a2dc719384428..d58e6e3251d670fbb9584244751f02ec7b62e2a0 100755
--- a/migration/20.10/2010.sql
+++ b/migration/20.10/2010.sql
@@ -352,6 +352,9 @@ SET dest_user = (
     WHERE item_mode = 'dest' AND item_type = 'user_id' AND listinstance.res_id = res_letterbox.res_id LIMIT 1
 );
 
+/* VISA CIRCUIT PARAMETERS */
+INSERT INTO parameters (id, description, param_value_int) VALUES ('minimumVisaRole', 'Nombre minimum de viseur dans les circuits de visa (0 pour désactiver)', 0);
+INSERT INTO parameters (id, description, param_value_int) VALUES ('maximumSignRole', 'Nombre maximum de signataires dans les circuits de visa (0 pour désactiver)', 0);
 
 /* ORDER ON CHRONO */
 CREATE OR REPLACE FUNCTION order_alphanum(text) RETURNS text AS $$
diff --git a/src/app/entity/controllers/ListTemplateController.php b/src/app/entity/controllers/ListTemplateController.php
index e068e23d484d178be392365aa4a82e9361edf8d5..03c0abb2d57261ad4358f7f3f1331f22842b44d4 100755
--- a/src/app/entity/controllers/ListTemplateController.php
+++ b/src/app/entity/controllers/ListTemplateController.php
@@ -129,11 +129,14 @@ class ListTemplateController
         }
 
         $allowedTypes = ['diffusionList', 'visaCircuit', 'opinionCircuit'];
-        $check = Validator::stringType()->notEmpty()->validate($body['type']) && in_array($body['type'], $allowedTypes);
-        $check = $check && Validator::arrayType()->notEmpty()->validate($body['items']);
-        $check = $check && (Validator::stringType()->notEmpty()->validate($body['title']) || Validator::stringType()->notEmpty()->validate($body['description']));
-        if (!$check) {
-            return $response->withStatus(400)->withJson(['errors' => 'Bad allowed types']);
+        if (!Validator::stringType()->notEmpty()->validate($body['type']) || !in_array($body['type'], $allowedTypes)) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body type is empty or not an allowed types']);
+        }
+        if (!Validator::arrayType()->notEmpty()->validate($body['items'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body items is empty or not an array']);
+        }
+        if (!Validator::stringType()->notEmpty()->validate($body['title'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body title is empty or not a string', 'lang' => 'templateNameMandatory']);
         }
 
         if (!empty($body['entityId'])) {
@@ -151,7 +154,7 @@ class ListTemplateController
 
         $control = ListTemplateController::controlItems(['items' => $body['items'], 'type' => $body['type'], 'entityId' => $body['entityId']]);
         if (!empty($control['errors'])) {
-            return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
+            return $response->withStatus(400)->withJson(['errors' => $control['errors'], 'lang' => $control['lang']]);
         }
 
         $listTemplateId = ListTemplateModel::create([
@@ -217,7 +220,7 @@ class ListTemplateController
 
         $control = ListTemplateController::controlItems(['items' => $body['items'], 'type' => $listTemplate['type'], 'entityId' => $listTemplate['entity_id']]);
         if (!empty($control['errors'])) {
-            return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
+            return $response->withStatus(400)->withJson(['errors' => $control['errors'], 'lang' => $control['lang']]);
         }
 
         ListTemplateModel::update([
@@ -691,10 +694,10 @@ class ListTemplateController
 
         if ($args['type'] == 'visaCircuit') {
             if ($minimumVisaRole != 0 && $nbVisaRole < $minimumVisaRole) {
-                return ['errors' => 'Template does not have enough visa users'];
+                return ['errors' => 'Template does not have enough visa users', 'lang' => 'notEnoughVisaUser'];
             }
             if ($maximumSignRole != 0 && $nbSignRole > $maximumSignRole) {
-                return ['errors' => 'Template have too many sign users'];
+                return ['errors' => 'Template have too many sign users', 'lang' => 'tooManySignUser'];
             }
         }
 
diff --git a/src/frontend/app/actions/visa-send-signature-book-action/send-signature-book-action.component.html b/src/frontend/app/actions/visa-send-signature-book-action/send-signature-book-action.component.html
index ae0295e7c6d58570b2f9d9e4bff535a07d03a049..b563b4fe451b4c9f23576d0dfe1a1c3d407ade07 100755
--- a/src/frontend/app/actions/visa-send-signature-book-action/send-signature-book-action.component.html
+++ b/src/frontend/app/actions/visa-send-signature-book-action/send-signature-book-action.component.html
@@ -21,10 +21,10 @@
                 </div>
                 <div *ngIf="!visaNumberCorrect || !signNumberCorrect" class="alert-message alert-message-danger" role="alert">
                     <p *ngIf="!visaNumberCorrect">
-                        {{'lang.notEnoughVisaUser' | translate}}
+                        {{'lang.notEnoughVisaUser' | translate}} ({{'lang.requiredVisaUser' | translate: {min: minimumVisaRole} }})
                     </p>
                     <p *ngIf="!signNumberCorrect">
-                        {{'lang.tooManySignUser' | translate}}
+                        {{'lang.tooManySignUser' | translate}} ({{'lang.authorizedSignUser' | translate: {max: maximumSignRole} }})
                     </p>
                 </div>
                 <div *ngIf="resourcesError.length > 0" class="alert-message alert-message-danger mailList" role="alert">
diff --git a/src/lang/lang-en.json b/src/lang/lang-en.json
index 406b6ef14a999652480aa8669401a3aadda0e856..76500c362fab6531ea9bb8ace1a6addea6e5169c 100644
--- a/src/lang/lang-en.json
+++ b/src/lang/lang-en.json
@@ -2170,5 +2170,7 @@
     "noPreviousValid": "No valid previous user",
     "youCannotUnsign": "You do not have the right to <b>unsign</b> this document. You must be the person who signed this document.",
     "notEnoughVisaUser": "Not enough approvers",
-    "tooManySignUser": "Too many signatories"
+    "tooManySignUser": "Too many signatories",
+    "requiredVisaUser": "{{min}} approvers required",
+    "authorizedSignUser": "{{max}} signatories authorized"
 }
diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json
index 068b0a68207ab46bde98f55b583c30f324bc016b..264b58379817b1ec805fbc137b3e1e731e9ede39 100644
--- a/src/lang/lang-fr.json
+++ b/src/lang/lang-fr.json
@@ -2162,5 +2162,8 @@
     "noPreviousValid": "Aucun utilisateur précédent valide",
     "youCannotUnsign" : "Vous n'avez pas le droit de <b>dé-signer</b> ce document. Vous devez être la personne qui a signé ce document.",
     "notEnoughVisaUser": "Nombre de viseur insuffisant",
-    "tooManySignUser": "Nombre de signataire maximum dépassé"
+    "tooManySignUser": "Nombre de signataire maximum dépassé",
+    "templateNameMandatory": "Nom du modèle obligatoire",
+    "requiredVisaUser": "{{min}} viseur(s) requis",
+    "authorizedSignUser": "{{max}} signataire(s) autorisé(s)"
 }
diff --git a/test/unitTests/app/entity/ListTemplateControllerTest.php b/test/unitTests/app/entity/ListTemplateControllerTest.php
index e68f7cec46ddc87847de97cf79e066acd56cca55..a1e37ee47e289027b83abbabd2a0bbce8197dbb4 100755
--- a/test/unitTests/app/entity/ListTemplateControllerTest.php
+++ b/test/unitTests/app/entity/ListTemplateControllerTest.php
@@ -126,7 +126,7 @@ class ListTemplateControllerTest extends TestCase
         $response     = $listTemplateController->create($fullRequest, new \Slim\Http\Response());
         $this->assertSame(400, $response->getStatusCode());
         $responseBody = json_decode((string)$response->getBody(), true);
-        $this->assertSame('Bad allowed types', $responseBody['errors']);
+        $this->assertSame('Body type is empty or not an allowed types', $responseBody['errors']);
 
         $body = [
             'type'        => 'diffusionList',