diff --git a/internal/models/desk.go b/internal/models/desk.go
new file mode 100644
index 0000000000000000000000000000000000000000..fb314d5f5ae9a4891c933a604edda068cf7be11a
--- /dev/null
+++ b/internal/models/desk.go
@@ -0,0 +1,121 @@
+package models
+
+import (
+	"encoding/json"
+	"net/http"
+	"strconv"
+	"strings"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+)
+
+func (d *DataHandler) HandleDesk(w http.ResponseWriter, r *http.Request) {
+	id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/Desk/"))
+	switch method := r.Method; method {
+	case "GET":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN", "CAPTURER", "VISUALIZER":
+			d.getDesk(w, r, id)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "POST":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.postDesk(w, r)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+
+	case "PUT":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.putDesk(w, r, id)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "DELETE":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.deleteDesk(w, r, id)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	default:
+		http.Error(w, "method not allowed", 400)
+	}
+}
+
+func (d *DataHandler) getDesk(w http.ResponseWriter, r *http.Request, id int) {
+	if id != 0 {
+		var o Desk
+		if err := d.db.First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		json.NewEncoder(w).Encode(o)
+	} else {
+		var o []Desk
+		d.db.Find(&o)
+		json.NewEncoder(w).Encode(o)
+	}
+}
+
+func (d *DataHandler) postDesk(w http.ResponseWriter, r *http.Request) {
+	var o Desk
+	err := json.NewDecoder(r.Body).Decode(&o)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	// Check that SectionID exist
+	var section Section
+	if err := d.db.First(&section, o.SectionID).Error; err != nil {
+		http.Error(w, ErrorParentNotFound, http.StatusInternalServerError)
+		return
+	}
+
+	d.db.Create(&o)
+	d.db.Last(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) putDesk(w http.ResponseWriter, r *http.Request, id int) {
+	var o Desk
+	if err := d.db.First(&o, id).Error; err != nil {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+		return
+	}
+	var desk Desk
+	err := json.NewDecoder(r.Body).Decode(&desk)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	o.Name = desk.Name
+	o.WitnessDesk = desk.WitnessDesk
+	o.Subscribed = desk.Subscribed
+	d.db.Save(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) deleteDesk(w http.ResponseWriter, r *http.Request, id int) {
+	if id != 0 {
+		var o Desk
+		if err := d.db.First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		d.db.Delete(&o)
+	} else {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+	}
+}
diff --git a/internal/models/models.go b/internal/models/models.go
index c5e20768f717a4283c81a2a906123bf125de2489..9fea419465b07c1c59709a4b7cef4a4f27b34c4d 100644
--- a/internal/models/models.go
+++ b/internal/models/models.go
@@ -80,8 +80,8 @@ type Desk struct {
 	DeletedAt   *time.Time `json:"-"`
 	SectionID   uint
 	Name        string
-	Subscribed  uint
 	WitnessDesk bool
+	Subscribed  uint
 }
 
 // Party
@@ -224,6 +224,8 @@ func (d *DataHandler) ProcessAPI(w http.ResponseWriter, r *http.Request) {
 		d.HandleArea(w, r)
 	case "Section":
 		d.HandleSection(w, r)
+	case "Desk":
+		d.HandleDesk(w, r)
 	}
 
 }
diff --git a/internal/models/section.go b/internal/models/section.go
index debe567e6a41bf693d5e1a0179dd13753d5eb563..fb6356d868808013e50ed66d771e1aabf1072e6f 100644
--- a/internal/models/section.go
+++ b/internal/models/section.go
@@ -41,7 +41,7 @@ func (d *DataHandler) HandleSection(w http.ResponseWriter, r *http.Request) {
 	case "DELETE":
 		switch auth.GetLoggedUserTechnical(w, r).Role {
 		case "ADMIN":
-			d.deleteAreaAdmin(w, r, id)
+			d.deleteSection(w, r, id)
 		case "CAPTURER", "VISUALIZER":
 			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
 		default:
diff --git a/internal/rootmux/admin_test.go b/internal/rootmux/admin_test.go
index 242760e1de9f6999a7ad126f698825f97deed6bf..a18624e1607c260db95199ddba59812cf20397dc 100644
--- a/internal/rootmux/admin_test.go
+++ b/internal/rootmux/admin_test.go
@@ -60,6 +60,17 @@ func AdminTests(t *testing.T) {
 		// Update a section
 		do("PUT", "/api/Section/1", xsrfHeader, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"5"}`, 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"5","Desks":[]}`)
 
+		// Create a Desk
+		do("POST", "/api/Desk", xsrfHeader, `{"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`)
+		// Get the desk
+		do("GET", "/api/Desk/1", xsrfHeader, ``, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`)
+		// Get all the desks
+		do("GET", "/api/Desk/", xsrfHeader, ``, 200, `[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]`)
+		// Update a desk
+		do("PUT", "/api/Desk/1", xsrfHeader, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":false,"Subscribed":3587}`, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":false,"Subscribed":3587}`)
+
+		// Delete a desk
+		do("DELETE", "/api/Desk/1", xsrfHeader, ``, 200, ``)
 		// Delete a section
 		do("DELETE", "/api/Section/1", xsrfHeader, ``, 200, ``)
 		// Delete an area
diff --git a/internal/rootmux/capturer_test.go b/internal/rootmux/capturer_test.go
index c77549f44974af67d3014b4d9b8a36b82976b2d9..1bd6e863198cbe3695cfb0a708dd22d2eec97064 100644
--- a/internal/rootmux/capturer_test.go
+++ b/internal/rootmux/capturer_test.go
@@ -60,14 +60,25 @@ func CapturerTests(t *testing.T) {
 		// Create a section should fail with 405
 		do("POST", "/api/Section", xsrfHeader, `{"AreaID":1,"Name":"Section 1","MapID":"1"}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Get a section
-		do("GET", "/api/Section/1", xsrfHeader, "", 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[]}`)
+		do("GET", "/api/Section/1", xsrfHeader, "", 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]}`)
 		// Get all the sections
-		do("GET", "/api/Section/", xsrfHeader, "", 200, `[{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[]}]`)
+		do("GET", "/api/Section/", xsrfHeader, "", 200, `[{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]}]`)
 		// Update a section should fail with 405
 		do("PUT", "/api/Section/1", xsrfHeader, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1"}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a section should fail with 405
 		do("DELETE", "/api/Section/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
 
+		// Create a desk should fail with 405
+		do("POST", "/api/Desk", xsrfHeader, `{"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Get a desk
+		do("GET", "/api/Desk/1", xsrfHeader, "", 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`)
+		// Get all the desks
+		do("GET", "/api/Desk/", xsrfHeader, "", 200, `[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]`)
+		// Update a desk should fail with 405
+		do("PUT", "/api/Desk/1", xsrfHeader, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":false,"Subscribed":3587}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Delete a desk should fail with 405
+		do("DELETE", "/api/Desk/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
+
 	}
 	// Do a in memory login with an known admin
 	do("POST", "/Login", noH, `{"login": "capturer","password": "password"}`, 200, "")
diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go
index 61d6a2f31e745e9912808b7ee78c006e0f9f93d5..c98e56807570f073af224f38e7f393fbc4a11eee 100644
--- a/internal/rootmux/rootmux_test.go
+++ b/internal/rootmux/rootmux_test.go
@@ -141,9 +141,11 @@ func resetDataWithData(t *testing.T) {
 		// Create a capturer
 		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":2,"Name":"Capturer"}`, 200, `{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":null}`)
 		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":3,"Name":"Capturer"}`, 200, `{"ID":2,"UserID":3,"Name":"Capturer","DeskRounds":null}`)
+
 		do("POST", "/api/Election", xsrfHeader, `{"Name":"Grand Lyon 2020","BallotType":"metropolitan-direct"}`, 200, `{"ID":1,"Name":"Grand Lyon 2020","BallotType":"metropolitan-direct","Areas":null,"Rounds":null}`)
 		do("POST", "/api/Area", xsrfHeader, `{"ElectionID":1,"Name":"Area 1","SeatNumber":9,"MapID":"1"}`, 200, `{"ID":1,"ElectionID":1,"Name":"Area 1","SeatNumber":9,"MapID":"1","Sections":null}`)
 		do("POST", "/api/Section", xsrfHeader, `{"AreaID":1,"Name":"Section 1","MapID":"1"}`, 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":null}`)
+		do("POST", "/api/Desk", xsrfHeader, `{"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}`)
 
 	}
 	do("POST", "/Login", noH, `{"login": "admin","password": "password"}`, 200, "")
diff --git a/internal/rootmux/visualizer_test.go b/internal/rootmux/visualizer_test.go
index 8f436112f549077295cb4a0e9b03fce70498cdff..f7c3289ca925b9c0651802147ed36d6b59ac6c2c 100644
--- a/internal/rootmux/visualizer_test.go
+++ b/internal/rootmux/visualizer_test.go
@@ -58,9 +58,9 @@ func VisualizerTests(t *testing.T) {
 		// Create a section should fail with 405
 		do("POST", "/api/Section", xsrfHeader, `{"AreaID":1,"Name":"Section 1","MapID":"1"}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Get a section
-		do("GET", "/api/Section/1", xsrfHeader, "", 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[]}`)
+		do("GET", "/api/Section/1", xsrfHeader, "", 200, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]}`)
 		// Get all the sections
-		do("GET", "/api/Section/", xsrfHeader, "", 200, `[{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[]}]`)
+		do("GET", "/api/Section/", xsrfHeader, "", 200, `[{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1","Desks":[{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587}]}]`)
 		// Update a section should fail with 405
 		do("PUT", "/api/Section/1", xsrfHeader, `{"ID":1,"AreaID":1,"Name":"Section 1","MapID":"1"}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a section should fail with 405