diff --git a/example.json b/example.json
index 5411f335b92ed7b40193699e13a4f1593c7e74e2..2a6360cbb9efbab86ed4e219a4ec019a57dfb72f 100644
--- a/example.json
+++ b/example.json
@@ -4,7 +4,9 @@
         "metadata": {
             "title": "Hello Krustcea !",
             "description": "An example website",
-            "image": "https://example.com/images/ex_pic.png",
+            "image": [
+                "https://example.com/images/ex_pic.png"
+            ],
             "css": [],
             "js": [],
             "url_slug": "",
diff --git a/src/main.rs b/src/main.rs
index ee1186c445214b527ffcde5bb01bac734c6c1dc0..b8d0cc219c7c70b5c3e0cf791b001e553b83ad69 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -58,7 +58,9 @@ async fn main() -> std::io::Result<()> {
                     .service(
                         web::scope("/auth")
                             .wrap(AuthService {})
-                            .service(service::admin_workspace),
+                            .service(service::admin_workspace)
+                            .service(service::add_page)
+                            .service(service::get_page_data),
                     ),
             )
             .service(service::files::favicon)
diff --git a/src/service/admin.rs b/src/service/admin.rs
index aa53c867c57a07cb331b8f569683365ce918aba6..d10c659fbeabc6da0a1bd1bd3f1302fc0db84747 100644
--- a/src/service/admin.rs
+++ b/src/service/admin.rs
@@ -1,13 +1,14 @@
+use crate::website::{Page, WebSite};
 use crate::AppState;
 use actix_web::{
     get, post,
-    web::{Data, Form},
-    HttpRequest, HttpResponse, Responder,
+    web::{Data, Form, Json},
+    HttpRequest, HttpResponse,
 };
 use std::sync::RwLock;
 
 #[get("/workspace")]
-async fn admin_workspace() -> impl Responder {
+async fn admin_workspace() -> HttpResponse {
     // TODO return admin static web view with js application
     actix_web::HttpResponse::Ok().body("Welcome Admin")
 }
@@ -23,7 +24,7 @@ async fn admin_authenticate(
     credentials: Form<Credentials>,
     app_state: Data<RwLock<AppState>>,
     req: HttpRequest,
-) -> impl Responder {
+) -> HttpResponse {
     let (admin_username, admin_pwd, cookie_name) = {
         let app_state = app_state
             .read()
@@ -57,7 +58,7 @@ async fn admin_authenticate(
 }
 
 #[get("/login")]
-pub async fn admin_login() -> impl Responder {
+pub async fn admin_login() -> HttpResponse {
     // TODO create a module with built-in admin static views
     HttpResponse::Ok().body(
         "
@@ -88,3 +89,42 @@ pub async fn admin_login() -> impl Responder {
 ",
     )
 }
+
+#[derive(serde::Deserialize, Clone)]
+pub struct AddPageData {
+    parent_page_id: usize,
+    new_page: Page,
+}
+
+#[post("/add-page")]
+pub async fn add_page(
+    website: Data<RwLock<WebSite>>,
+    add_page_data: Json<AddPageData>,
+) -> HttpResponse {
+    match website
+        .write()
+        .expect("Couldn't acquire website write lock")
+        .add_page(add_page_data.parent_page_id, add_page_data.new_page.clone())
+    {
+        Ok(()) => HttpResponse::Ok().finish(),
+        Err(msg) => {
+            HttpResponse::BadRequest().body(format!("Error adding new page to website - {}", msg))
+        }
+    }
+}
+
+#[get("/page-data/{id}")]
+pub async fn get_page_data(
+    website: Data<RwLock<WebSite>>,
+    id: actix_web::web::Path<usize>,
+) -> HttpResponse {
+    let id = id.into_inner();
+    match website
+        .read()
+        .expect("Couldn't acquire website read lock")
+        .get_page(id)
+    {
+        Some(page) => HttpResponse::Ok().json(page),
+        None => HttpResponse::NotFound().body(format!("Page with id {} was not found", id)),
+    }
+}
diff --git a/src/website/page.rs b/src/website/page.rs
index 6559b016f6b2cc3f906d1df042e6b774c1eede35..cc95c8857eb642b9b806b7aab59d5cc91f97da0b 100644
--- a/src/website/page.rs
+++ b/src/website/page.rs
@@ -318,6 +318,10 @@ impl Page {
 
         map
     }
+
+    pub fn add_sub_page(&mut self, page: Page) {
+        self.sub_pages.push(page);
+    }
 }
 
 #[cfg(test)]
diff --git a/src/website/website.rs b/src/website/website.rs
index fc53a9b12e47735819ac154887354cadd4b55f8d..3168dbf3162d0298ac4aff448e1d0bb3fd927ec1 100644
--- a/src/website/website.rs
+++ b/src/website/website.rs
@@ -115,47 +115,38 @@ impl WebSite {
         Ok(self.clone())
     }
 
-    fn init_last_generated_page_id(&mut self) {
-        let mut ids = vec![self.root_page.get_id()];
-
-        fn collect_ids(p: &Page, ids: &mut Vec<usize>) {
-            for sp in p.sub_pages.iter() {
-                ids.push(sp.get_id());
-                collect_ids(sp, ids);
+    pub fn get_all_pages_as_vec(&self) -> Vec<&Page> {
+        let mut pages = Vec::new();
+        fn collect_pages<'a>(root: &'a Page, vec: &mut Vec<&'a Page>) {
+            vec.push(root);
+            for p in root.sub_pages.iter() {
+                collect_pages(p, vec);
             }
         }
-
-        collect_ids(&self.root_page, &mut ids);
-
-        self.last_generated_page_id = *ids.iter().max().unwrap();
+        collect_pages(&self.root_page, &mut pages);
+        pages
     }
 
-    fn generate_pages_ids(&mut self) {
-        self.init_last_generated_page_id();
+    fn max_page_id(&self) -> usize {
+        self.get_all_pages_as_vec()
+            .iter()
+            .map(|p| p.get_id())
+            .max()
+            .unwrap()
+    }
 
-        fn generate_page_id(page: &mut Page, last_generated_page_id: &mut usize) {
-            if page.get_id() == 0 {
-                *last_generated_page_id += 1;
-                page.set_id(*last_generated_page_id);
-            }
-        }
+    fn generate_pages_ids<'a>(&'a mut self) {
+        self.last_generated_page_id = self.max_page_id();
 
-        fn rec_gen_ids(
-            p: &mut Page,
-            gen_id: fn(&mut Page, &mut usize),
-            last_generated_page_id: &mut usize,
-        ) {
-            gen_id(p, last_generated_page_id);
-            for sp in p.sub_pages.iter_mut() {
-                rec_gen_ids(sp, gen_id, last_generated_page_id)
+        fn process_page(page: &mut Page, id: &mut usize) {
+            *id += 1;
+            page.set_id(*id);
+            for sp in page.sub_pages.iter_mut() {
+                process_page(sp, id);
             }
         }
 
-        rec_gen_ids(
-            &mut self.root_page,
-            generate_page_id,
-            &mut self.last_generated_page_id,
-        );
+        process_page(&mut self.root_page, &mut self.last_generated_page_id);
     }
 
     pub fn save(&self, config: &AppConfig) -> std::io::Result<()> {
@@ -172,4 +163,131 @@ impl WebSite {
 
         Ok(())
     }
+
+    fn find_page(page: &Page, match_id: usize) -> Option<&Page> {
+        if page.get_id() == match_id {
+            return Some(page);
+        }
+        for sp in page.sub_pages.iter() {
+            if let Some(page) = Self::find_page(sp, match_id) {
+                return Some(page);
+            };
+        }
+        None
+    }
+
+    fn find_page_mut(page: &mut Page, match_id: usize) -> Option<&mut Page> {
+        if page.get_id() == match_id {
+            return Some(page);
+        }
+
+        for sp in page.sub_pages.iter_mut() {
+            if let Some(p) = Self::find_page_mut(sp, match_id) {
+                return Some(p);
+            };
+        }
+
+        None
+    }
+
+    pub fn get_page(&self, id: usize) -> Option<&Page> {
+        Self::find_page(&self.root_page, id)
+    }
+
+    pub fn add_page(&mut self, parent_page_id: usize, page: Page) -> Result<(), String> {
+        let id = self.last_generated_page_id + 1;
+        let parent_page = Self::find_page_mut(&mut self.root_page, parent_page_id);
+        match parent_page {
+            Some(pp) => {
+                let mut page = page;
+                page.set_id(id);
+                pp.add_sub_page(page);
+            }
+            None => {
+                return Err(format!(
+                    "Parent page with id {} was not found",
+                    parent_page_id
+                ))
+            }
+        }
+
+        self.last_generated_page_id = id;
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod test_website {
+    use super::*;
+
+    fn test_website(pth: &PathBuf) -> WebSite {
+        WebSiteBuilder::testing(pth).build().unwrap()
+    }
+
+    fn remove_test_dir(pth: &PathBuf) {
+        let _ = std::fs::remove_dir_all(pth);
+    }
+
+    #[test]
+    fn test_pages_id() {
+        let test_dir = &PathBuf::from("./test");
+        let ws = test_website(&test_dir);
+
+        assert_eq!(ws.last_generated_page_id, 3);
+        assert_eq!(ws.max_page_id(), 3);
+        assert!(!ws.get_all_pages_as_vec().iter().any(|p| p.get_id() == 0));
+        remove_test_dir(&test_dir);
+    }
+
+    #[test]
+    fn test_get_page() {
+        let test_dir = &PathBuf::from("./test");
+        let ws = test_website(&test_dir);
+        let page = ws.get_page(1);
+        assert!(page.is_some());
+        let page = ws.get_page(2);
+        assert!(page.is_some());
+        let page = ws.get_page(3);
+        assert!(page.is_some());
+        let page = ws.get_page(4);
+        assert!(page.is_none());
+        remove_test_dir(&test_dir);
+    }
+
+    #[test]
+    fn test_add_page() {
+        let test_dir = &PathBuf::from("./test");
+        let mut ws = test_website(&test_dir);
+        let test_new_page: &'static str = "
+{
+    \"template_name\": \"TEST TEMPLATE\",
+    \"metadata\": {
+        \"title\": \"Added page\",
+        \"description\": \"Added page descr\",
+        \"image\": [\"https://example.com/images/ex_pic.png\"],
+        \"css\": [],
+        \"js\": [],
+        \"url_slug\": \"\",
+        \"lang\": \"en\"
+    },
+    \"body\": [
+        {
+            \"tag\": \"h1\",
+            \"text\": \"Added page\"
+        }
+    ],
+    \"sub_pages\": []
+}
+        ";
+
+        let new_page: Page = serde_json::from_str(test_new_page).unwrap();
+        let added = ws.add_page(1, new_page);
+        assert!(added.is_ok());
+        let retrieved = ws.get_page(4);
+        assert!(retrieved.is_some());
+        let retrieved = retrieved.unwrap();
+        assert_eq!(retrieved.metadata.title, "Added page");
+        remove_test_dir(&test_dir);
+    }
 }