diff --git a/images/actions_example.png b/images/actions_example.png
new file mode 100644
index 00000000..04209da6
Binary files /dev/null and b/images/actions_example.png differ
diff --git a/images/config_panel_example.png b/images/config_panel_example.png
new file mode 100644
index 00000000..5665a3c9
Binary files /dev/null and b/images/config_panel_example.png differ
diff --git a/images/config_panel_toml_example.png b/images/config_panel_toml_example.png
new file mode 100644
index 00000000..c72e0baf
Binary files /dev/null and b/images/config_panel_toml_example.png differ
diff --git a/packaging_apps_actions.md b/packaging_apps_actions.md
new file mode 100644
index 00000000..595b30db
--- /dev/null
+++ b/packaging_apps_actions.md
@@ -0,0 +1,144 @@
+# Applications Actions
+
+
For now, all those features are EXPERIMENTAL
+and aren't ready for production and are probably going to change again, if you
+still decide to use them don't expect them to be stable and follow to core
+development of YunoHost otherwise they might randomly breaks on your apps
+
+
+Applications "actions" is a packaging feature that allow you to ship with your
+application a list of "actions" executable from both the cli and the admin
+interfaces.
+
+"actions" are a list of custom commands that, optionally, has arguments (like
+the installation script of an application has arguments) and once called will
+called a specific selected command with those arguments. Like an "actions"
+restart service with a argument "service name" could called the command
+`systemctl restart $some_service` (but don't that specific action in your app,
+it's just for example purpose).
+
+Like the installation page generated from the manifest those actions can accept
+a list of arguments.
+
+Their main purpose is to expose procedures that a sysadmin would normally do on
+CLI but that your application user would want to do but don't have the
+knowledge to do by themselves via ssh (or are just too lazy for that).
+
+For example those could be:
+
+* importing data in a application
+* generate a custom backup
+* start a procedure like synchronising file with the file system (nextcloud for example)
+* purge a local cache
+* restart some services
+* modify a theme
+
+Actions looks like this in the admin interface:
+
+![actions admin screenshot](images/actions_example.png)
+
+## How to add actions to your application
+
+Adding actions to your application is pretty simple as it is very similar to
+writing your manifest for the application installation.
+
+You need to write an `actions.toml` file in your application at the root level
+like the `manifest.toml`/`manifest.json`.
+
+The general pattern looks like this:
+
+```toml
+[first_action]
+name = "some name"
+description = "some description that will be displayed"
+
+# can be a bash command like so:
+command = "echo pouet $YNH_ACTION_FIRST_ARGUMENT"
+# or a path to a script like
+command = "/path/to/some/stuff --some-flag $YNH_ACTION_FIRST_ARGUMENT"
+
+user = "root" # optional
+cwd = "/" # optional, "current working directory", by default it's "/etc/yunohost/apps/the_app_id"
+ # also the variable "$app" is available in this variable and will be replace with the app id
+ # for example you can write "/var/www/$app"
+accepted_return_codes = [0, 1, 2, 3] # optional otherwise only "0" will be a non enorous return code
+
+ [first_action.arguments]
+ # here, you put a list of arguments exactly like in manifest.toml/json
+ [first_action.arguments.first_argument]
+ type = "string"
+ ask = "service to restart"
+ example = "nginx"
+
+ ... # add more arguments here if needed
+ # you can also have actions without arguments
+
+[another_action]
+name = "another name"
+command = "systemctl restart some_service"
+
+ [another_action.arguments]
+ [another_action.arguments.argument_one]
+ type = "string"
+ ask = "some stuff"
+ example = "stuff"
+
+ ... # add more arguments here if needed
+ # you can also have actions without arguments
+```
+
+You can have as much actions as you want and from zero to as many arguments you want.
+
+If you prefer, you can also write your actions in json like manifest.json:
+
+```json
+[{
+ "id": "restart_service",
+ "name": "Restart service",
+ "command": "echo pouet $YNH_ACTION_SERVICE",
+ "user": "root", # optional
+ "cwd": "/", # optional
+ "accepted_return_codes": [0, 1, 2, 3], # optional
+ "description": {
+ "en": "a dummy stupid exemple or restarting a service"
+ },
+ "arguments": [
+ {
+ "name": "service",
+ "type": "string",
+ "ask": {
+ "en": "service to restart"
+ },
+ "example": "nginx"
+ }
+ ]
+},
+{
+ ... # other action
+}]
+```
+
+## How to use actions
+
+### In the admin
+
+For now since those features are still
+experimental you won't find any direct links to the app actions on the app
+page
+
+The actions are located on https://some_domain.tld/yunohost/admin/#/apps/$app_id/actions
+
+## With the CLI
+
+The CLI API is very similar to application installation. You have 2 commands:
+
+* `yunohost app list $app`
+* `yunohost app run $app $action_id` ("$action_id" is the this between "[]"
+ like "[another_action]" in the example)
+
+`list` will obviously give you all actions for an application.
+
+`run` will run an existing action for an application and will ask, if needed,
+values for arguments. Like with `yunohost app install` you can use the `-a` and
+pass arguments in the HTTP POST arguments format (like
+`&path=/app&domain=domain.tld&other_value=stuff`)
diff --git a/packaging_apps_advanced.md b/packaging_apps_advanced.md
new file mode 100644
index 00000000..c2bb905e
--- /dev/null
+++ b/packaging_apps_advanced.md
@@ -0,0 +1,40 @@
+# Advanced features of apps packaging
+
+For now, all those features are EXPERIMENTALS
+and aren't ready for production and are probably going to change again, if you
+still decide to use them don't expect them to be stable and follow to core
+development of YunoHost otherwise they might randomly breaks on your apps
+
+
+## Actions
+
+Actions allow you to ship a list of executables "actions" related to your
+application, for example that could be:
+
+* import data
+* generate a custom backup
+* start a procedure
+* regenerate a local cache
+
+[Full documentation](#/packaging_apps_actions)
+
+Example in the admin:
+
+![actions admin screenshot](images/actions_example.png)
+
+## Configuration Panel
+
+Configuration or "config_panel" allow you to offer a custom configuration panel
+for your application integrated into YunoHost administration panel. This allow
+you to expose whatever configuration you want for your application and this is
+generally used to handle an application configuration file when this is not
+possible inside the application itself.
+
+This is generally also the place where you want to add the option to make an
+application public or not.
+
+[Full documentation](#/packaging_apps_config_panel)
+
+Example in the admin:
+
+![actions admin screenshot](images/config_panel_example.png)
diff --git a/packaging_apps_config_panel.md b/packaging_apps_config_panel.md
new file mode 100644
index 00000000..29d48e55
--- /dev/null
+++ b/packaging_apps_config_panel.md
@@ -0,0 +1,298 @@
+# Applications Configuration Panel
+
+For now, all those features are EXPERIMENTAL
+and aren't ready for production and are probably going to change again, if you
+still decide to use them don't expect them to be stable and follow to core
+development of YunoHost otherwise they might randomly breaks on your apps
+
+
+Configuration panel, or "config_panel", is a way for an application to ship a
+custom configuration panel available in the YunoHost's admin interface for the
+application. This is generally used to replace the "you need to manually edit
+this configuration file (or files) in whatever format/language for this
+application in cli and do all those complex commands" to "just use to
+configuration panel to change the options of the application".
+
+Yes, this is one place to add this so asked "how can I make my application from
+public to private and vice versa" user request.
+
+config_panel is probably the most complex YunoHost apps feature as you'll need
+to write both a description of the panel in toml and a script that will need to
+both work in a "display mode" and "handle inputs" mode. But this is still very
+doable and very worth it if you need it.
+
+Here how it looks like in the admin interface:
+
+![actions admin screenshot](images/config_panel_example.png)
+
+## Usage
+
+### Admin interface
+
+The configuration panel for an application can be accessed with this url:
+
+ https://my_domain.tld/yunohost/admin/#/apps/$app_id/config-panel
+
+For now since those features are still
+experimental you won't find any direct links to the app actions on the app
+page
+
+### CLI
+
+For now the CLI API for the config panel is not very good at all, you can still
+use it but it's really impracticable.
+
+* `yunohost app config show-panel $app_id` will show the panel. **But for now
+it's very broken and will asked question for unfilled value of the panel**.
+
+* `yunohost app config apply` will call the script with apply and... no values
+ since you aren't passing them, except if you are ready to play with the `-a`
+ flag and pass every global value in the HTTP POST format (protip: you don't)
+
+In conclusion: don't use the CLI for now, we need to design something better.
+
+## How to add a config_ panel to your application
+
+### config_panel.toml
+
+Firs, you need to write a `config_panel.toml` (or `config_panel.json` if you
+REALLY wants it but we really don't recommend it has it is very error prone and
+frustrating to write by hand) that will be located at the root of you
+application, next to the manifest.json/toml. It looks like this:
+
+```toml
+version = "0.1" # version number, not used yet but important
+name = "name that will be displayed on the admin"
+
+[section_id]
+name = "name of the section that will be displayed"
+
+ [section_id.sub_section_id]
+ name = "sub section"
+
+ # those arguments are in yunohost argument format like manifest.json
+ [section_id.sub_section_id.option_id]
+ ask = "the text displayed for the option"
+ type = "argument_option"
+ default = true
+ help = "A public Leed will be accessible for third party apps.
By turning on 'anonymous readers' in Leed configuration, you can made your feeds public."
+
+ [section_id.sub_section_id.another_option_id]
+ ...
+
+ [section_id.another_sub_section_id]
+ name = "stuff"
+
+[another_section_id]
+name = "stuff"
+
+...
+```
+
+
+And a real world example with the rendered admin:
+
+![config_panel_toml_example](images/config_panel_toml_example.png)
+
+As a text format:
+
+```toml
+version = "0.1"
+name = "Leed configuration panel"
+
+[main]
+name = "Leed configuration"
+
+ [main.is_public]
+ name = "Public access"
+
+ # those arguments are in yunohost argument format
+ [main.is_public.is_public]
+ ask = "Is it a public website ?"
+ type = "boolean"
+ default = true
+ help = "A public Leed will be accessible for third party apps.
By turning on 'anonymous readers' in Leed configuration, you can made your feeds public."
+
+
+ [main.overwrite_files]
+ name = "Overwriting config files"
+
+ [main.overwrite_files.overwrite_nginx]
+ ask = "Overwrite the nginx config file ?"
+ type = "boolean"
+ default = true
+ help = "If the file is overwritten, a backup will be created."
+
+ [main.overwrite_files.overwrite_phpfpm]
+ ask = "Overwrite the php-fpm config file ?"
+ type = "boolean"
+ default = true
+ help = "If the file is overwritten, a backup will be created."
+
+...
+```
+
+### the scripts/config script
+
+To make your configuration panel functional you need write a "config" script
+that will be location in the "script" folder like the "install" script. This
+script will be called at 2 different occasions:
+
+* when the configuration panel is displayed and yunohost needs to fill the values
+* when the configuration is modified by the user
+
+Every option of the configuration panel will be send to the script
+following this naming convention:
+
+```bash
+YNH_{section_id}_{sub_section_id}_{option_id} (everything in upper case)
+```
+
+For example, this option value:
+
+```toml
+[main]
+name = "Leed configuration"
+
+ [main.is_public]
+ name = "Public access"
+
+ # those arguments are in yunohost argument format
+ [main.is_public.is_public]
+ ...
+```
+
+Will be available under this name in the config script:
+
+```
+YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC
+```
+
+Also, the same "scripts/config" script is called in both situation. To differentiate
+those situation the first argument passed to the config script is either "show"
+or "apply".
+
+A common pattern to handle that is to write your script following this pattern:
+
+```bash
+show_config() {
+ # do stuff
+}
+
+apply_config() {
+ # do stuff
+}
+
+case $1 in
+ show) show_config;;
+ apply) apply_config;;
+esac
+```
+
+#### The "show" part
+
+The show part is when the user ask to see the current state of the
+configuration panel (like opening to configuration panel page on the admin
+interface). The role of the scripts/config script here is to gather all the
+relevant information, by for example parsing a configuration file or querying a
+database, and communicate it to YunoHost. To do so, you need to use the helper
+`ynh_return` like so:
+
+```bash
+ynh_return "YNH_CONFIG_SOME_VARIABLE_NAME=some_value"
+```
+
+For example, for this config_panel:
+
+```toml
+[main]
+name = "Leed configuration"
+
+ [main.is_public]
+ name = "Public access"
+
+ # those arguments are in yunohost argument format
+ [main.is_public.is_public]
+ ...
+```
+
+You would do:
+
+```bash
+ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
+```
+
+If you don't provide any value for a configuration **the default value will be used**.
+
+Expanding our previous example you would have this scripts/config script:
+
+```bash
+show_config() {
+ ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
+}
+
+apply_config() {
+ # do stuff
+}
+
+case $1 in
+ show) show_config;;
+ apply) apply_config;;
+esac
+```
+
+#### The "apply" part
+
+The "apply" part is called when the user click on "submit" on the configuration
+page on the admin interface. This part is simpler to write:
+
+- the scripts/config will be called with "apply"
+- all the value in the config panel (modified or not) are available as global
+ variable in the script following the format `YNH_{section_id}_{sub_section_id}_{option_id}`
+ (exactly the same than for show)
+- the script is responsible for doing whatever it wants with those information
+- once the script as succeeded, the admin interface display the config panel
+ again so the script is called again in "show" mode
+
+Expanding the previous script that could look like that:
+
+```bash
+show_config() {
+ ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
+}
+
+apply_config() {
+ value=$YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC
+ # do some stuff with value
+}
+
+case $1 in
+ show) show_config;;
+ apply) apply_config;;
+esac
+```
+
+Or if you want a full useless simple script that store the value in a file,
+this can looks like this:
+
+```bash
+dummy_config_file="dummy_config_file.ini"
+
+show_config() {
+ if [ -e $dummy_config_file ]
+ then
+ ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=$(cat $dummy_config_file)"
+ fi
+
+ # the default value will be used
+}
+
+apply_config() {
+ echo $YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC > $dummy_config_file
+}
+
+case $1 in
+ show) show_config;;
+ apply) apply_config;;
+esac
+```