diff --git a/README.md b/README.md
index 1a18073..af24ca7 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,8 @@ You may want to set data.json as a volume to be able to make changes on the fly
 
 ![matrix room screenshot](screenshots/example2.png)
 
+
+![Adding questions from matrix](screenshots/adding-questions.gif)
 ## Features in the works
 * Alerts
 * Dynamic configuration
diff --git a/commands.py b/commands.py
index 804f8c6..212387b 100644
--- a/commands.py
+++ b/commands.py
@@ -1,161 +1,233 @@
 import random
+from turtle import update
 import features
-jokes = [
-    ["Testing","Testing you!"],
-    ["singing pokemon","Jiggalypuff! 🎙️"]
-]
-#jokes = []
 
-def handle_command(state,sender,message):
+api = features.API()
+debug = False
+
+def handle_command(sender, message):
+    state = api.get_user_state(sender)
     for command in commands:
-            if message.find(command)==0:
-                result = commands[command](state,message,sender)           
-                return result
+        if message.find(command) == 0:
+            result = commands[command](state, message, sender)
+            return result
     if len(state) > 0:
+        if debug == 1:
+            return commands[state[0]](state, message, sender)
         try:
-            result = commands[state[0]](state,message,sender)
+            result = commands[state[0]](state, message, sender)
             return result
         except Exception as e:
             return {
-                "state":[],
-                "response":f"⚠️Error⚠️ \n {e}"
+                "response": f"⚠️Error⚠️"
             }
-        
+
     return {
-        "response":None,
-        "state":state
+        "response": "",
     }
 
-    """
-    Knock-knock implimentation
-    
-    when you receive message, read state.
-    user: knock knock
-    bot: who's there? -> bot responds and registers state 
-    (user.state=[knock-knock])
-    user: {statement}
-    bot: {statement} who? -> bot responds and stores statement
-    (user.stage=[knock-knock,{statement}])
-    user: {punchline}
-    bot: Nice one! -> bot saves knock-knock joke
-    """
-    
-def nevermind(state,message,sender):
+
+def get_faq_string():
+    return api.get_faq_string()
+
+
+def nevermind(state, message, sender):
+    api.update_user_state(sender, [])
     return {
-        "response":"starting over.",
-        "state":[]
+        "response": "starting over."
     }
 
-def knock_knock(state,message,sender):
-    #return {response:"",state:""}
-    try:
-        if state[0] != "knock knock":
-            #clear the state
-            state = []  
-    except:
-        pass
-    if len(state) == 0:
-        state.append("knock knock")
-        return {
-            "response":"Who's there?",
-            "state": state
-        }
-    if len(state) == 1:
-        state.append(message)
-        return {
-            "response":message + " who?",
-            "state":state
-        }
-    if len(state) == 2:
-        state.append(message)
-        jokes.append([
-            state[1],state[2]
-        ])
-        print("joke registered.")
-        return {
-            "response":"Hah! very funny!",
-            "state":[]
-        }
-        
-    return {
-        "response":"Cleared.",
-        "state":[]
-    }
+# faq
 
-"""'joke' command
-    -------------
-    user:!joke
-    bot:Knock knock -> bot initializes state
-    (user.state=[joke])
-    user: Who's there?
-    bot: {statement} -> bot responds with chosen joke
-    (user.state=[joke,chosenjoke])
-    user: {statement} who?
-    bot: 
-    
-    """
-def joke(state,message,sender):
-    if len(jokes) == 0:
-        return {
-            "response":"I don't know any jokes...",
-            "state":[]
-        }    
-    
+
+def get_faq(state, message, sender):
     if len(state) == 0:
         return {
-            "response":"Knock knock",
-            "state":["joke"]
+            "response": api.get_faq_string()
+        }
+    return {
+        "response": api.get_faq_string()
+    }
+
+
+def add_question(state, message, sender):
+    if len(state) == 0:
+        api.update_user_state(sender, ["!add question"])
+        return {
+            'response': "Please enter the question title."
         }
     elif len(state) == 1:
-        if message.find("there?") > 0 :
-            #get random joke index
-            state.append(random.randint(0,len(jokes)-1))
-            return {
-                "response":jokes[state[1]][0],
-                "state":state
-            }
-        else:
-            return {
-                "response":"ask, \"who's there?\"",
-                "state":state
-            }
+        state.append(message)
+        api.update_user_state(sender, state)
+        return {
+            'response': 'Please enter the answer to the question.'
+        }
     elif len(state) == 2:
-        if  message.find("who?") > 0:
+        state.append(message)
+        api.update_user_state(sender, state)
+        state = api.get_user_state(sender)
+        return {
+            'response': f"Your question is:\n---\n# {state[1]}\n{state[2]}\n\n---\nIf this is what you want respond with `confirm`\n If you'd like to start over respond with `restart`\n Respond with `nevermind` to cancel entirely"
+        }
+    elif len(state) == 3:
+        if message == 'confirm':
+            api.add_question({
+                'question': state[1],
+                'answer': state[2]
+            })
+            api.update_user_state(sender, [])
             return {
-                "response":jokes[state[1]][1],
-                "state":[]               
+                'response': 'Question added.'
+            }
+        elif message == 'restart':
+            api.update_user_state(sender, ['!add question'])
+            return {
+                'response': 'Please enter the question title.'
             }
         else:
             return {
-                "response":"ask, \""+ jokes[state[1]][0] +" who?\"",
-                "state":state
+                'response': f"Your question is:\n# {state[1]}\n{state[2]}\n\nIf this is what you want respond with `confirm`\n If you'd like to start over respond with `restart`\n Respond with `nevermind` to cancel entirely"
             }
+
+    return {
+        'response': None
+    }
+
+
+def update_question(state, message, sender):
+    if len(api.data['faq']['questions']) == 0:
+        api.update_user_state(sender, [])
+        return {
+            'response': "No questions registered."
+        }
+    elif len(state)==0:
+        api.update_user_state(sender,"!update question")
+        return {
+            "response":f"Choose a question to update:\n {api.get_faq_questions}"
+        }
+    return {
+        'response': None,
+
+    }
+
+
+def remove_question(state, message, sender):
+    if len(api.data['faq']['questions']) == 0:
+        api.update_user_state(sender, [])
+        return {
+            'response': "No questions registered."
+        }
+    elif len(state)==0:
+        api.update_user_state(sender,["!remove question"])
+        return {
+            "response":f"Choose a question to remove:\n {api.get_faq_questions()}"
+        }
+    elif len(state) == 1:
+        try:
+            int(message)
+        except:
+            return {"response":"Please enter a number."}
+        state.append(message)
+        if  int(state[1]) < len(api.data['faq']['questions']) and int(state[1]) >=0:
+            if debug == True:
+                api.remove_question(int(state[1]))
+                api.update_user_state(sender,[])
+                return {
+                    'response':'Question removed'
+                }
+            else:
+                try:
+                    api.update_user_state(sender,[])
+                    api.remove_question(int(state[1]))
+                    return {
+                        'response':'Question removed'
+                    }
+                except:
+                    pass
+                    
+        api.update_user_state(sender,["!remove question"])
+        return {
+            'response':'Please enter the correct question #'
+        }
+        
         
     return {
-        "response":None,
-        "state":[]
-    }
-    
-    """
+        'response': None,
+
+    }
+
+
+def update_header(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def remove_header(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def update_footer(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def remove_footer(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def add_admin(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def remove_admin(state, message, sender):
+    return {
+        'response': None,
+
+    }
+
+
+def appointments():
+
+    return {
+        "response": None,
+        state: []
+    }
+
 
-    """  
-    def appointments():
-        
-        return {
-            "response":None,
-            state:[]
-        }
 commands = {
-    "nevermind":nevermind,
-    "knock knock":knock_knock,
-    "joke":joke
+    "nevermind": nevermind,
+    "!faq": get_faq,
+    "!add question": add_question,
+    "!remove question": remove_question,
+    "!update question": update_question,
+    "!update header": update_header,
+    "!remove header": remove_header,
+    "!update footer": update_footer,
+    "!remove footer": remove_footer,
+    "!add admin": add_admin,
+    "!remove admin": remove_admin,
+
 }
 
 
-
 if __name__ == '__main__':
+    user = "admin"
     msg = ""
+    debug = True
     while msg != "exit":
         msg = input("user:")
-        user = handle_command(user,msg)
-        #print("state:",user)
\ No newline at end of file
+        print("bot:"+handle_command(user, msg)['response'])
+        # print("state:",user)
diff --git a/data-example.json b/data-example.json
index 67fbcaf..08d3fb0 100644
--- a/data-example.json
+++ b/data-example.json
@@ -5,17 +5,17 @@
     "faq": {
         "header": "# Simple example FAQ",
         "questions": [{
-                "question": "# What is the meaning of life?",
+                "question": "What is the meaning of life?",
                 "answer": "42.",
                 "key_phrases": ["meaning", "life"]
             },
             {
-                "question": "# Who is the coolest pokemon?",
+                "question": "Who is the coolest pokemon?",
                 "answer": "Mewtwo! 🐈",
                 "key_phrases": ["coolest", "pokemon"]
             },
             {
-                "question": "# What is the coolest programming language?",
+                "question": "What is the coolest programming language?",
                 "answer": "🐍 python!",
                 "key_phrases": ["coolest", "programming", "language"]
             }
diff --git a/features.py b/features.py
index 6f4a12f..cdb6adf 100644
--- a/features.py
+++ b/features.py
@@ -11,20 +11,23 @@ class API:
         with open('data.json') as f:
             self.data = json.loads(f.read())
             # Only refresh data when a change is made
-            
+    def update_data(self):
+        with open('data.json','r') as f:
+            self.data = json.loads(f.read()) 
     def save(self):
         with open('data.json','w') as f:
             f.write(json.dumps(self.data,indent=2))
             return True
         return False
 
-    #Administration
-    
 
+    #Administration
     def is_admin(self,handle):
+        self.update_data()
         #return bool
         pass
     def add_admin(self,handle):
+        self.update_data()
         #return bool
         if self.is_admin(handle):
             return True
@@ -33,6 +36,7 @@ class API:
             self.save()
             return True
     def remove_admin(self,handle):
+        self.update_data()
         #return bool
         if self.is_admin(handle):
             i = self.data["admins"].index(handle)
@@ -42,38 +46,83 @@ class API:
         else:
             return True
     
+    
+    #state management
+    def get_user_state(self,handle):
+        self.update_data()
+        if handle not in self.data["users"]:
+            self.data["users"][handle]={"state":[]}
+            self.save()
+        return self.data["users"][handle]["state"]
+    
+    def update_user_state(self,handle,state):
+        self.update_data()
+        current_state = self.get_user_state(handle)
+        self.data["users"][handle]["state"] = state
+        self.save()
+        return True    
+    
+    
     #FAQ
+    def get_faq_string(self):
+        self.update_data()
+        faq = self.data["faq"]
+        return faq["header"] + "".join(
+            ["\n# "+q["question"]+"\n"+q["answer"]+"\n" for q in faq["questions"]]
+        ) + "\n"+ faq["footer"]
+        
+    def get_faq_questions(self):
+        self.update_data()
+        questions = self.data['faq']['questions']
+        response = ""
+        index = 0
+        for question in questions:
+            response += f"[{index}]:{question['question']}\n"
+            index += 1
+        return response
+            
+            
+        
     def get_header(self):
+        self.update_data()
         return self.data["faq"]["header"]
     def set_header(self,hdr):
+        self.update_data()
         #return bool
         self.data["faq"]["header"] = hdr
         self.save()
         return True
     def get_questions(self):
+        self.update_data()
         #return questions
         return self.data["faq"]["questions"]
     def add_question(self,qtn):
+        self.update_data()
         #return bool
         self.data["faq"]["questions"].append(qtn)
         self.save()
         return True
     def remove_question(self,qtn_i):
+        self.update_data()
         #return bool
         self.data["faq"]["questions"].pop(qtn_i)
         self.save()
         return True
     def update_question(self,qtn_i,qtn):
+        self.update_data()
         #return bool
         self.data["faq"]["questions"][qtn_i]=qtn
         return True
     
     #Meetings
-    def get_meetings():
+    def get_meetings(self):
+        self.update_data()
         pass
-    def request_meeting():
+    def request_meeting(self):
+        self.update_data()
         pass
-    def accept_meeting():
+    def accept_meeting(self):
+        self.update_data()
         pass
     
     
diff --git a/main.py b/main.py
index b721f89..54bd85e 100644
--- a/main.py
+++ b/main.py
@@ -3,58 +3,22 @@ import nio
 import simplematrixbotlib as botlib
 import commands
 
-#TODO move state functionality entirely to features.py
-
 data = json.loads(open('data.json').read())
-dfaq = data["faq"]
-userstate = data['users']
-faq_text = dfaq["header"] + "".join(["\n"+q["question"]+"\n"+q["answer"]
-                                    for q in dfaq["questions"]]) + "\n\n"+dfaq["footer"]
-
 creds = botlib.Creds(
-        data["homeserver"],
-        data['username'],
-        data['password']
-    )
+    data["homeserver"],
+    data['username'],
+    data['password']
+)
 bot = botlib.Bot(creds)
-PREFIX = '!'
-
-
-def load_faq():
-    dfaq = json.loads(open('data.json').read())["faq"]
-    return dfaq["header"] + "".join(["\n"+q["question"]+"\n"+q["answer"] for q in dfaq["questions"]]) + "\n\n"+dfaq["footer"]
-
-def save_userstate():
-    with open('data.json','w') as f:
-        f.write(json.dumps(data,indent=4))
 
 @bot.listener.on_message_event
 async def faq(room, message):
-    if message.sender not in userstate:
-        userstate[message.sender] = {"state":[]}
-        save_userstate()
-    
-    
-    state = userstate[message.sender]['state']
-    result = commands.handle_command(state,message.sender,message.body)
-    if  result['response']!= None:
-        state = result['state']
-        userstate[message.sender]['state'] = result['state']
-        save_userstate()
+    result = commands.handle_command(message.sender, message.body)
+    if result['response'] != None and result['response'] != "":
         await bot.api.send_markdown_message(
             room.room_id,
             result['response']
         )
-    
-    
-    match = botlib.MessageMatch(room, message, bot, PREFIX)
-    #print(f"{message.sender} : {message.body}")
-    if match.is_not_from_this_bot() and match.prefix() and match.command(
-            "faq"):
-        await bot.api.send_markdown_message(
-            room.room_id,
-            load_faq())
-
 
 
 @bot.listener.on_custom_event(nio.InviteMemberEvent)
@@ -62,31 +26,7 @@ async def example(room, event):
     if event.membership == "join":
         await bot.api.send_markdown_message(
             room.room_id,
-            load_faq()
+            commands.get_faq_string()
         )
 
-
-def get_questions():
-    return json.loads(open('data.json').read())["faq"]["questions"]
-    
-
-@bot.listener.on_message_event
-async def faqresponse(room, message):
-    match = botlib.MessageMatch(room, message, bot, PREFIX)
-    if match.is_not_from_this_bot():
-        response = ""
-        questions = get_questions()
-        for q in questions:
-            if sum([ 1 for kp in q["key_phrases"] if kp in message.body]) == len(q["key_phrases"]):
-                response += q["question"] + "\n" + q["answer"]+"\n"
-        if response != "":
-            await bot.api.send_markdown_message(
-                room.room_id,
-                response + dfaq["footer"]
-            )
-
-
-
-
-            
 bot.run()
diff --git a/screenshots/adding-questions.gif b/screenshots/adding-questions.gif
new file mode 100644
index 0000000..925e413
Binary files /dev/null and b/screenshots/adding-questions.gif differ