diff --git a/docs/API spec.md b/docs/API spec.md
index b240e7c..308a732 100644
--- a/docs/API spec.md
+++ b/docs/API spec.md
@@ -143,3 +143,9 @@ DiscordMessage consists of the following:
### Language support
RcGcDw implements i18n with gettext and already exposes Translations instance with its `src.i18` module. formatters_i18n variable is used for instance of all formatters inside base directory.
+
+### Pre/post hooks
+**Path**: `src.api.hook`
+There are two decorator functions available in the module: `pre_hook` and `post_hook`. They don't take arguments and simply register the function as a hook.
+Pre-hook functions take the following arguments: `context` ([Context object](#Context)) and `change` (dict object with change).
+Post-hook functions take the following arguments: `message` ([Discord message object](#DiscordMessage)), `metadata` ([Discord message metadata](#DiscordMessageMetadata)) and `context` ([Context object](#Context))
\ No newline at end of file
diff --git a/extensions/__init__.py b/extensions/__init__.py
index fd83a9a..c2cc1c1 100644
--- a/extensions/__init__.py
+++ b/extensions/__init__.py
@@ -13,4 +13,5 @@
# You should have received a copy of the GNU General Public License
# along with RcGcDw. If not, see .
-import extensions.base
\ No newline at end of file
+import extensions.base
+import extensions.hooks
\ No newline at end of file
diff --git a/extensions/hooks/__init__.py b/extensions/hooks/__init__.py
new file mode 100644
index 0000000..669ca03
--- /dev/null
+++ b/extensions/hooks/__init__.py
@@ -0,0 +1,16 @@
+# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
+#
+# RcGcDw is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RcGcDw is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RcGcDw. If not, see .
+
+import extensions.hooks.example_hook
\ No newline at end of file
diff --git a/extensions/hooks/example_hook.py b/extensions/hooks/example_hook.py
new file mode 100644
index 0000000..425cccc
--- /dev/null
+++ b/extensions/hooks/example_hook.py
@@ -0,0 +1,28 @@
+# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
+#
+# RcGcDw is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RcGcDw is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RcGcDw. If not, see .
+
+from src.api.hook import pre_hook, post_hook
+
+
+@pre_hook
+def example_pre_hook(context, change):
+ if context.event == "edit":
+ print("I'm an edit with {} bytes changed!".format(change.get("newlen", 0) - change.get("oldlen", 0)))
+
+
+@post_hook
+def example_post_hook(message, metadata, context):
+ print("Our Discord message looks as follows: ")
+ print(message)
diff --git a/src/rcgcdw.py b/src/rcgcdw.py
index 9ce4afe..a4c28c7 100644
--- a/src/rcgcdw.py
+++ b/src/rcgcdw.py
@@ -58,6 +58,7 @@ def load_extensions():
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
except ImportError:
logger.critical("No extensions module found. What's going on?")
+ logger.exception("Error:")
sys.exit(1)
storage = datafile