diff --git a/README.md b/README.md
index 7a7e49d74e820d38b1523f9dddfbd4af6922fc11..cff8054004769e43be1f34a869b809dda554842b 100644
--- a/README.md
+++ b/README.md
@@ -9,14 +9,14 @@
 
 Clone the contents of this repository and run
 
-```
+```sh
 mvn clean package
 ```
 
 This will create a distribution folder called `jams` in the root folder. You can
 then launch the server by running
 
-```
+```sh
 cd jams
 java -jar jams-launcher.jar
 ```
@@ -88,7 +88,7 @@ chmod +x .git/hooks/pre-commit
 ## Development Docker container
 
 A development environment with react hot reloading can be created using:
-```
+```sh
 docker build -f Dockerfile -t jams:dev --target dev .
 docker run -it -p 3000:3000 -p 8080:8080 -p 35000:35000 \
     -v $(pwd)/jams-react-client/src:/app/jams-react-client/src \
@@ -96,6 +96,13 @@ docker run -it -p 3000:3000 -p 8080:8080 -p 35000:35000 \
     --rm jams:dev
 ```
 
+`setup_jams.sh` can be used to quickly do the initial setup.
+The script creates user alice, bob, charlie and danny, all with the password "a",
+and they all belong to the group "defaultGroup".
+```sh
+./extras/scripts/setup_jams.sh
+```
+
 Note: It is possible that after 15 minutes, the user's token expires, the server
 will answer with a "You are not authentified" and forget to put the CORS
 headers, thus the browser will refuse to read the response. In this case, you
@@ -103,7 +110,7 @@ will need to restart the server.
 
 ## Generate jams with Docker
 The following commands will generate the userguide and the jars needed:
-```
+```sh
 docker build -f Dockerfile -t jams:latest --target prod . \
     && CONTAINER=$(docker create jams:latest) \
     && docker cp $CONTAINER:/app/jams/. jams \
diff --git a/extras/scripts/setup_jams.sh b/extras/scripts/setup_jams.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8295d3db2448eda5ba9c40f2bb8ca1a4b68fff89
--- /dev/null
+++ b/extras/scripts/setup_jams.sh
@@ -0,0 +1,160 @@
+#!/usr/bin/env sh
+
+set -e
+
+HOST='http://localhost:8080'
+
+LAST_CURL_RESPONSE=''
+BEARER=''
+GROUP_ID=''
+
+post() {
+    _route=$1
+    _data=$2
+
+    printf '\n\n%s %s\n' "$_method" "$_route"
+    LAST_CURL_RESPONSE=$(curl "$HOST$_route" \
+        -sk \
+        -D /dev/stderr \
+        -H "Authorization: Bearer $BEARER" \
+        -H 'Content-Type: application/json;charset=UTF-8' \
+        --data-raw "$_data"
+    )
+    echo "$LAST_CURL_RESPONSE"
+}
+
+get_bearer() {
+    _method=$1
+    _route=$2
+
+    printf '\n\n%s %s\n' "$_method" "$_route"
+    BEARER=$(curl "$HOST$_route" \
+        -sk \
+        -D /dev/stderr \
+        -X "$_method" \
+        --data-raw '{"username":"admin","password":"admin"}'
+    )
+    BEARER=$(echo "$BEARER" | jq -r '.access_token')
+    echo "BEARER=$BEARER"
+}
+
+install_create_admin_account() {
+    get_bearer PUT /api/install/start
+}
+
+install_ca() {
+    # 5 years: 157784630000
+    post '/api/install/ca' \
+        '{"fields":{
+            "commonName":"myCommonName",
+            "organization":"myOrg",
+            "city":"myCity",
+            "state":"myState",
+            "country":"AI",
+            "lifetime":157784630000
+        }}'
+}
+
+install_auth() {
+    post '/api/install/auth' \
+        '{
+            "type":"LOCAL",
+            "localAuthSettings": {
+                "publicNameServer":"http://ns.jami.net",
+                "publicNames":false
+            }
+        }'
+}
+
+install_settings() {
+    post '/api/install/settings' \
+        '{
+            "serverDomain":"http://localhost:3000",
+            "crlLifetime":300000,
+            "deviceLifetime":31556952000,
+            "userLifetime":31556952000,
+            "sipConfig":null,
+            "signingAlgorithm":"SHA512WITHRSA"
+        }'
+}
+
+login() {
+    get_bearer POST '/api/login'
+}
+
+create_blueprint() {
+    _name=$1
+    post "/api/admin/policy?name=$_name" \
+        '{
+            "videoEnabled":true,
+            "publicInCalls":false,
+            "allowCertFromContact":true,
+            "allowCertFromHistory":true,
+            "allowCertFromTrusted":true,
+            "autoAnswer":false,
+            "peerDiscovery":true,
+            "accountDiscovery":true,
+            "accountPublish":true,
+            "rendezVous":false,
+            "defaultModerators":"",
+            "upnpEnabled":true,
+            "allowLookup":true
+        }'
+}
+
+create_group() {
+    _name=$1
+    _blueprint_name=$2
+
+    post '/api/admin/group' \
+        '{"name":"'"$_name"'","blueprintName":"'"$_blueprint_name"'"}'
+
+    GROUP_ID=$(echo "$LAST_CURL_RESPONSE" | jq -r '.id')
+}
+
+create_user() {
+    _username=$1
+    _password=$2
+    post '/api/admin/user' \
+        '{"username":"'"$_username"'","password":"'"$_password"'"}'
+
+    post '/api/admin/directory/entry' \
+        '{
+            "username":"'"$_username"'",
+            "password":"'"$_password"'",
+            "firstName":"",
+            "lastName":"",
+            "email":"",
+            "profilePicture":"",
+            "organization":"",
+            "faxNumber":"",
+            "phoneNumber":"",
+            "phoneNumberExtension":"",
+            "mobileNumber":"",
+            "jamiId":""
+        }'
+
+    post "/api/admin/group/members/$GROUP_ID" '{"username":"'"$_username"'"}'
+}
+
+install_setup() {
+    install_create_admin_account
+    install_ca
+    install_auth
+    install_settings
+}
+
+create_mock_data() {
+    _group_name='defaultGroup'
+    _blueprint_name='defaultBlueprint'
+    login
+    create_blueprint $_blueprint_name
+    create_group $_group_name $_blueprint_name
+    create_user alice a
+    create_user bob a
+    create_user charlie a
+    create_user danny a
+}
+
+install_setup
+create_mock_data