diff --git a/README.md b/README.md
index e984b10127053adad219a8232fe4308b3e0fe126..4ec4a684930f31d9cb2b0b5b5a6bf1c49657cbc4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# REST API CLIENT
+# Bash REST API client
 
 This is a bash solution to script REST API calls.
 
@@ -12,16 +12,21 @@ The specialties of this component are
 * The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request.
 * Caching support for GET requests with a given TTL: if you repeat a request to the same url and ttl was not reached yet then you continue with the cached result
 
-Source: <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client>
+👤 Author: Axel Hahn; Institute for Medical Education; University of Bern \
+📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client> \
+📜 License: GNU GPL 3.0 \
+📗 Docs: <https://os-docs.iml.unibe.ch/bash-rest-api-client/>
 
-License: GNU GPL 3
 
-## Requirements
+```text
+http.init
+http.makeRequest 'http://www.example.com/'
+```
 
-* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.)
-* Curl must be in the path
-* optional: sha1sum (for export function with autogenerated filenames only)
+This stores the response in a variable and has no output.
+Now you can get its data, eg
 
----
-
-[Installation](docs/10_Installation.md) | [Usage](docs/20_Usage.md) | [Examples](docs/30_Examples.md)
\ No newline at end of file
+* http.getStatuscode     - This returns the Http status code
+* http.getResponseHeader - print Http response header
+* http.getResponseData   - get data from curl
+* http.getResponse       - get response body
diff --git a/docs/10_Installation.md b/docs/10_Installation.md
deleted file mode 100644
index 1e67cab7fe0ba7a37b6c9299a00e8fc7a161bb3b..0000000000000000000000000000000000000000
--- a/docs/10_Installation.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Download
-
-
-Download the archive i.e. as zip:
-
-https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client/-/archive/master/bash-rest-api-client-master.zip
-
-(see other formats at the download button on https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client)
-
-# OR: Git clone
-
-```sh
-git clone https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client.git
-```
-
-# Copy somewhere
-
-Copy the file `rest-api-client.sh` anywhere you want.
-If you need it in a single script then copy it to its directory. If you need it more often then copy it to a folter of your PATH environment.
diff --git a/docs/10_Introduction.md b/docs/10_Introduction.md
new file mode 100644
index 0000000000000000000000000000000000000000..fbdf5069a7a65e4aec9242106cd6ea16820e1c10
--- /dev/null
+++ b/docs/10_Introduction.md
@@ -0,0 +1,21 @@
+## Introduction
+
+### Description
+
+This is a bash solution to script REST API calls.
+
+The specialties of this component are
+
+* It was build to simplify http calls and handle http response for scripts
+* After making a request the response stays is in memory. There is no output to any file to grep something or to cleanup after usage.
+* Its functions feel a bit like class methods, i.e. http.getResponse to get the response body or http.getResponseHeader for the Http response header
+* This component wraps curl - ist supports any http method
+* works with anonymous requests and Basic Authentication
+* The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request.
+* Caching support for GET requests with a given TTL: if you repeat a request to the same url and ttl was not reached yet then you continue with the cached result
+
+### Requirements
+
+* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.)
+* Curl must be in the path
+* optional: sha1sum (for export function with autogenerated filenames only)
diff --git a/docs/20_Installation.md b/docs/20_Installation.md
new file mode 100644
index 0000000000000000000000000000000000000000..4dc5de18f30ba8395c3213facd8092b4b9c0aec2
--- /dev/null
+++ b/docs/20_Installation.md
@@ -0,0 +1,26 @@
+## Installation
+
+### Get all files
+
+#### Git clone
+
+```sh
+git clone https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client.git
+```
+
+#### Download
+
+Download the archive i.e. as zip:
+
+<https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client/-/archive/master/bash-rest-api-client-master.zip>
+
+(see other formats at the download button on <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client>)
+
+#### Copy shell script somewhere
+
+Copy the file `rest-api-client.sh` anywhere you need it.
+If you need it in a single script then copy it to its directory. If you need it more often then copy it to a folter of your PATH environment.
+
+### Get the script only
+
+`wget https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client/-/raw/master/rest-api-client.sh`
diff --git a/docs/20_Usage.md b/docs/30_Usage.md
similarity index 84%
rename from docs/20_Usage.md
rename to docs/30_Usage.md
index 591344e563bf463fa7b67e9be9ad8bde33bc4fc8..d421e151b74bfe0cdd79040dcc08867c934f2f65 100644
--- a/docs/20_Usage.md
+++ b/docs/30_Usage.md
@@ -7,7 +7,7 @@ The "methods" start with "http" dot "[method]".
 
 You should start with *http.help* to get an overwiew.
 
-```sh
+```text
 #
 # step one: source the shell script
 #
@@ -18,6 +18,15 @@ $ . ./rest-api-client.sh
 #
 $ http.help
 
+
+Bash REST API client v0.8
+
+This is a bash solution to script REST API calls.
+
+Source:https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client
+License: GNU GPL 3
+
+
 INSTRUCTION:
 
 - Source the file once
@@ -31,11 +40,19 @@ INSTRUCTION:
       Enable or disable debugging infos during processing. It is written
       to STDERR.
 
-
 - initialize a request
 
+    setAccept ACCEPT
+      Set authentication with user and password for basic auth
+      Default: application/json
+
     setAuth AUTH:PASSWORD
-      set authentication
+      Set authentication with user and password for basic auth
+
+    setAuthorization TYPE TOKEN|HASH
+      Set authentication with Authorization header. 
+      As TYPE you can use Basic|Bearer|Negotiate|...
+      2nd param is the token or hased user+password
 
     http.setBody DATA
       set a body for POST/ PUT requests.
@@ -57,6 +74,10 @@ INSTRUCTION:
       Set a relative url for a request.
       This requires to use http.setBaseUrl before.
 
+    http.addHeader HEADER_LINE
+      Add a header line to the request.
+      This command can be repeated multiple times.
+
 - caching functions
 
     http.setCacheTtl SECONDS
@@ -103,7 +124,7 @@ INSTRUCTION:
         Get the http status as string Ok|Redirect|Error
 
       http.getStatuscode
-        Get the http status code of a request as integer
+        Get the http status code of a request as 3 digit integer
 
       http.isOk
         Check if the http response code is a 2xx
diff --git a/docs/30_Examples.md b/docs/40_Examples.md
similarity index 81%
rename from docs/30_Examples.md
rename to docs/40_Examples.md
index c0ca4d1aca570d535f2837227c01df9debbe7db0..e91c6e7c503638e2d22073beeb9dfd892b830db6 100644
--- a/docs/30_Examples.md
+++ b/docs/40_Examples.md
@@ -1,4 +1,4 @@
-# Preparation
+## Preparation
 
 A required step is sourcing the script to make the http.* function available in the current shell.
 
@@ -9,7 +9,7 @@ A required step is sourcing the script to make the http.* function available in
 
 Then you can follow the examples.
 
-# A first example
+## A first example
 
 This is quick introduction: we make a request and have a look to a few results.
 
@@ -67,7 +67,7 @@ url_effective:http://www.iml.unibe.ch/
 
 ```
 
-# Icinga2 API
+## Icinga2 API
 
 In that example we have a config for an api access with url, user and password.
 The docs url is not required for functionality. It will be shown on errors.
@@ -113,3 +113,32 @@ if [ $? -ne 0 ]; then
 fi
 echo "OK, ${myHost} was found."
 ```
+
+## Authentication with JWT token
+
+The snippet shows how to fetch a token first that will be added to be used in all following requests.
+
+```sh
+# ---------- settings
+URL=https://www.example.com/
+USER=...
+PASSWORD=...
+
+# ---------- init
+http.init
+http.setBaseUrl "${URL}"
+
+# ---------- 1st request: get a token
+http.setAuth "${USER}:${PASSWORD}"
+http.makeRequest GET "token"
+
+# fetch token 
+ACCESS_TOKEN=$(http.getResponse | jq -r .access_token)
+
+# Set token for authorization
+http.setAuthorization "Bearer ${ACCESS_TOKEN}"
+
+# ---------- Requests to app or api
+http.makeRequest GET "api"
+http.makeRequest GET "app"
+```
diff --git a/docs/_index.md b/docs/_index.md
index 5541390c9c284956728423f483189877201c6c62..2300b3ad7ebfe98cdcef1677fa3e1cec39c5dc8c 100644
--- a/docs/_index.md
+++ b/docs/_index.md
@@ -1,23 +1,11 @@
-# Description
-
-This is a bash solution to script REST API calls.
-
-The specialties of this component are
-
-* It was build to simplify http calls and handle http response for scripts
-* After making a request the response stays is in memory. There is no output to any file to grep something or to cleanup after usage.
-* Its functions feel a bit like class methods, i.e. http.getResponse to get the response body or http.getResponseHeader for the Http response header
-* This component wraps curl - ist supports any http method
-* works with anonymous requests and Basic Authentication
-* The response can be stored ... and reimported later. After import you can use the http.get* functions to fetch results from the former request.
-* Caching support for GET requests with a given TTL: if you repeat a request to the same url and ttl was not reached yet then you continue with the cached result
-
-Source: https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client
-
-License: GNU GPL 3
-
-# Requirements
-
-* Bash as shell (runs on Linux - or with Cygwin or other Bash implementations on MS Windows too.)
-* Curl must be in the path
-* optional: sha1sum (for export function with autogenerated filenames only)
+<html>
+<div class="hero">
+    <h2>Bash REST API client</h2>
+    
+</div>
+</html>
+
+👤 Author: Axel Hahn; Institute for Medical Education; University of Bern \
+📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client> \
+📜 License: GNU GPL 3.0 \
+📗 Docs: <https://os-docs.iml.unibe.ch/bash-rest-api-client/>
diff --git a/rest-api-client.sh b/rest-api-client.sh
index 2a55f363374498332234b5d9f4779e558b06240d..33dee2e0724aade1b00c128cfe192acf1e8423af 100644
--- a/rest-api-client.sh
+++ b/rest-api-client.sh
@@ -8,6 +8,10 @@
 # - curl
 # - sha1sum (optional; for export functionality with AUTOFILE only)
 # ----------------------------------------------------------------------
+# License: GPL 3.0
+# Source: <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client>
+# Docs: <https://os-docs.iml.unibe.ch/bash-rest-api-client/>
+# ----------------------------------------------------------------------
 # (1) source this script
 # (2) enter "http.help" to get a list of available commands
 # ----------------------------------------------------------------------
@@ -16,14 +20,16 @@
 # 2020-03-02  v0.5  axel.hahn@iml.unibe.ch  a few more response check functions
 # 2021-01-21  v0.6  axel.hahn@iml.unibe.ch  add Content-type in request header
 # 2022-01-11  v0.7  axel.hahn@iml.unibe.ch  fixes using shellcheck
+# 2024-10-09  v0.8  axel.hahn@unibe.ch      add setAuthorization; customize accept header, add custom request headers
 # ======================================================================
 
-  http_cfg__about="Bash REST API client v0.7"
+  http_cfg__about="Bash REST API client v0.8"
   typeset -i http_cfg__debug=0
   typeset -i http_cfg__cacheTtl=0
   http_cfg__cacheDir=/var/tmp/http-cache
   http_cfg__UA="${http_cfg__about}"
   http_cfg__prjurl="https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client"
+  http_cfg__docsurl="https://os-docs.iml.unibe.ch/bash-rest-api-client/"
 
 # --- curl meta infos to collect
 #     see variables in man curl --write-out param
@@ -97,6 +103,9 @@ EOH
     # grep "function http.[a-z]" $0 | sort
   }
 
+  # ......................................................................
+  #
+  # Initialize the client
   function http.init(){
     http._wd "${FUNCNAME[0]}()"
     which curl >/dev/null || http.quit
@@ -104,7 +113,10 @@ EOH
     # request vars
 
     http_req__auth=
-    http_req__auth=
+    http_req__authorization=
+    http_req__accept="application/json"
+    http_req__headers=()
+
     http_req__body=
     http_req__method=GET
     http_req__url=
@@ -120,7 +132,6 @@ EOH
     http_curl__writeout="\\n${http_req__dataprefix}${writevar}\\n"
 
     # cache
-    http_req__mode=undefined
     http_cfg__cacheTtl=0
     http_cfg__cacheFile=
 
@@ -131,7 +142,10 @@ EOH
     chmod 777 ${http_cfg__cacheDir} 2>/dev/null
   }
 
-  # execute the request
+  # ......................................................................
+  #
+  # Execute the request
+  #
   # param  string  optional: method; GET|POST|PUT|DELETE|...
   # param  string  optional: full url
   # param  string  optional: request body
@@ -140,8 +154,7 @@ EOH
 
     # --- handle optional prams
     if [ $# -ne 0 ]; then
-      echo "$1" | grep "^[A-Z]*$" >/dev/null
-      if [ $? -eq 0 ]; then
+      if echo "$1" | grep -q "^[A-Z]*$"; then
         http.setMethod "$1"
         shift 1
       fi
@@ -151,21 +164,19 @@ EOH
     # test -z "$1" || http.setFullUrl "$1"
 
     # --- detect caching
-    http_req__mode=REQUEST
-    useCache=0
-    makeRequest=1
+    local useCache=0
+    local makeRequest=1
     if [ $http_cfg__cacheTtl -gt 0 ] && [ "${http_req__method}" = "GET" ]; then
       useCache=1
       test -z "${http_cfg__cacheFile}" && http_cfg__cacheFile=$(http._genOutfilename "${http_cfg__cacheDir}/AUTOFILE")
       if [ -f "${http_cfg__cacheFile}" ]; then
         http.responseImport "${http_cfg__cacheFile}"
-        typeset -i local iAge
+        local iAge; typeset -i iAge
         iAge=$(http.getRequestAge)
         http._wd "INFO: Age of cache is $iAge sec  - vs TTL $http_cfg__cacheTtl sec - file $http_cfg__cacheFile"
         if [ $iAge -gt 0 ] && [ $iAge -lt $http_cfg__cacheTtl ]; then
           http._wd "INFO: Using cache"
           makeRequest=0
-          http_req__mode=CACHE
         else
           http._wd "INFO: Cache file will be updated after making the request"
           rm -f "${http_cfg__cacheFile}" 2>/dev/null
@@ -176,29 +187,25 @@ EOH
 
     # --- make the request
     if [ $makeRequest -eq 1 ]; then
-      http._wd "${FUNCNAME[0]}($1) ${http_req__method} ${http_req__fullurl}"
-      http_resp__all=$(
-        if [ -z "${http_req__body}" ]; then
-          curl -k -s \
-            -A "${http_cfg__UA}" \
-            -w "${http_curl__writeout}" \
-            -H 'Accept: application/json' \
-            -H 'Content-type: application/json' \
-            ${http_req__auth} \
-            -i "${http_req__fullurl}" \
-            -X "${http_req__method}"
-        else
-          curl -k -s \
-            -A "${http_cfg__UA}" \
-            -w "${http_curl__writeout}" \
-            -H 'Accept: application/json' \
-            -H 'Content-type: application/json' \
-            ${http_req__auth} \
-            -i "${http_req__fullurl}" \
-            -X "${http_req__method}" \
-            -d "${http_req__body}"
-        fi
-        ) || http.quit
+
+      # build curl parameters
+      local curl_params=(
+        -k 
+        -s
+        -i "${http_req__fullurl}"
+        -X "${http_req__method}"
+        -w "${http_curl__writeout}"
+        -A "${http_cfg__UA}" 
+      )
+      test -n "$http_req__auth"          && curl_params+=( -u "$http_req__auth" )
+      test -n "$http_req__authorization" && curl_params+=( -H "Authorization: $http_req__authorization" )
+      test -n "$http_req__accept"        && curl_params+=( -H "Accept: $http_req__accept" )
+      test -n "$http_req__body"          && curl_params+=( -d "${http_req__body}" )
+      curl_params+=( "${http_req__headers[@]}" )
+
+      http._wd "${FUNCNAME[0]}($1) ${http_req__method} ${http_req__fullurl}"      
+      http_resp__all=$( curl "${curl_params[@]}") || http.quit
+
       http._wd "OK - Curl finished the http request ... processing data"
       http_resp__neutral=$(http._fetchAllAndReformat)
       if [ $useCache -eq 1 ]; then
@@ -211,7 +218,8 @@ EOH
 
   # ......................................................................
   #
-  # show error message with last return code and quit with this exitcode
+  # Show error message with last return code and quit with this exitcode
+  #
   # no params
   function http.quit(){
     rc=$?
@@ -252,7 +260,10 @@ EOH
   # GETTER
   # ======================================================================
 
-  # get the response header or response body
+  # ......................................................................
+  #
+  # Get the response header or response body
+  #
   # param  string  what to return; one of header|body
   function http._fetchResponseHeaderOrBody(){
     http._wd "${FUNCNAME[0]}($1)"
@@ -274,6 +285,10 @@ EOH
       fi
     done
   }
+
+  # ......................................................................
+  #
+  # Get the response data
   function http._fetchResponseData(){
     http._wd "${FUNCNAME[0]}()"
     echo "${http_resp__all}" | sed "s#${http_req__dataprefix}#\n${http_req__dataprefix}#" | grep "${http_req__dataprefix}" | tail -1 | cut -f 2- -d "|" | sed "s#|#\n#g" | grep -v "${http_req__dataprefix}" | while read -r line; do
@@ -281,6 +296,9 @@ EOH
     done
   }
 
+  # ......................................................................
+  #
+  # Generate the dump with request and response
   function http._fetchAllAndReformat(){
     http._wd "${FUNCNAME[0]}()"
     IFS=''
@@ -307,6 +325,11 @@ EOH
     echo $line END
   }
 
+  # ......................................................................
+  #
+  # Get a section from dump data
+  #
+  # param  string  what to return; one of HEADER|DATA|BODY
   function http._getFilteredResponse(){
     http._wd "${FUNCNAME[0]}($1)"
     echo "${http_resp__neutral}" | grep "^#_${1}_|"  | cut -f 2- -d "|"
@@ -314,17 +337,23 @@ EOH
 
   # ---------- PUBLIC REQUEST GETTER
 
+  # ......................................................................
+  #
+  # Get timestamp of the response
   function http.getRequestTs(){
     http._wd "${FUNCNAME[0]}()"
     http._getFilteredResponse REQUEST | grep "^timestamp" | cut -f 2 -d ":"
   }
 
-  # get age of the response in sec.
+  # ......................................................................
+  #
+  # Get age of the response in sec.
   # It is especially useful after responseImport
+  #
   function http.getRequestAge(){
     http._wd "${FUNCNAME[0]}()"
-    typeset -i local iAge
-    typeset -i local iTs
+    local iAge; typeset -i iAge
+    local iTs; typeset -i iTs
     iTs=$( http.getRequestTs )
     iAge=$( date +%s )-${iTs}
     echo "$iAge"
@@ -332,29 +361,41 @@ EOH
 
   # ---------- PUBLIC RESPONSE GETTER
 
-  # get response body
+  # ......................................................................
+  #
+  # Get response body
   function http.getResponse(){
     http._wd "${FUNCNAME[0]}()"
     http._getFilteredResponse BODY
   }
-  # get curl data of this request with status, transferred bytes, speed, ...
+
+  # ......................................................................
+  #
+  # Get curl data of this request with status, transferred bytes, speed, ...
   function http.getResponseData(){
     http._wd "${FUNCNAME[0]}()"
     http._getFilteredResponse DATA
   }
-  # get response header
+
+  # ......................................................................
+  #
+  # Get response header
   function http.getResponseHeader(){
     http._wd "${FUNCNAME[0]}()"
     http._getFilteredResponse HEADER
   }
 
-  # get raw response (not available after import)
+  # ......................................................................
+  #
+  # Get raw response (not available after import)
   function http.getResponseRaw(){
     http._wd "${FUNCNAME[0]}()"
     echo "${http_resp__all}"
   }
 
-  # get Http status as string OK|Redirect|Error
+  # ......................................................................
+  #
+  # Get Http status as string OK|Redirect|Error
   function http.getStatus(){
     http._wd "${FUNCNAME[0]}($1)"
     http.isOk       >/dev/null && echo OK
@@ -362,44 +403,61 @@ EOH
     http.isError    >/dev/null && echo Error
   }
 
-  # get Http status code of the request as 3 digit number
+  # ......................................................................
+  #
+  # Get Http status code of the request as 3 digit number
   function http.getStatuscode(){
     http._wd "${FUNCNAME[0]}()"
     http.getResponseData | grep "^http_code:" | cut -f 2 -d ":"
   }
 
-  # was response a 2xx status code?
+  # ......................................................................
+  #
+  # Check: was response a 2xx status code?
   # output is a statuscode if it matches ... or empty
   # Additionally you can verify the return code
+  #
   # $? -eq 0 means YES
   # $? -ne 0 means NO
   function http.isOk(){
     http._wd "${FUNCNAME[0]}()"
     http.getStatuscode | grep '2[0-9][0-9]'
   }
-  # was the repsonse a redirect?
+
+  # ......................................................................
+  #
+  # Was the repsonse a redirect?
   function http.isRedirect(){
     http._wd "${FUNCNAME[0]}()"
     http.getStatuscode | grep '3[0-9][0-9]'
   }
 
-  # was the repsonse a client error (4xx or 5xx)
+  # ......................................................................
+  #
+  # Was the repsonse a client error (4xx or 5xx)
   function http.isError(){
     http._wd "${FUNCNAME[0]}()"
     http.getStatuscode | grep '[45][0-9][0-9]'
   }
-  # was the repsonse a client error (4xx)
+
+  # ......................................................................
+  #
+  # Was the repsonse a client error (4xx)
   function http.isClientError(){
     http._wd "${FUNCNAME[0]}()"
     http.getStatuscode | grep '4[0-9][0-9]'
   }
-  # was the repsonse a client error (5xx)
+
+  # ......................................................................
+  #
+  # Was the repsonse a client error (5xx)
   function http.isServerError(){
     http._wd "${FUNCNAME[0]}()"
     http.getStatuscode | grep '5[0-9][0-9]'
   }
 
-
+  # ......................................................................
+  #
   # dump information about request and response
   function http.dump(){
     http._wd "${FUNCNAME[0]}()"
@@ -410,13 +468,15 @@ EOH
   # Import/ Export
   # ======================================================================
 
+  # ......................................................................
+  #
   # helper to replace "AUTOFILE" with something uniq using full url
+  #
   # param  string  import or export filename
   function http._genOutfilename(){
     http._wd "${FUNCNAME[0]}($1)"
-    echo "$1" | grep "AUTOFILE" >/dev/null
-    if [ $? -ne 0 ]; then
-      echo $1
+    if echo "$1" | grep -q "AUTOFILE"; then
+      echo "$1"
     else
       local sum
       sum=$(echo ${http_req__fullurl} | sha1sum )
@@ -426,7 +486,8 @@ EOH
     fi
   }
 
-
+  # ......................................................................
+  #
   # export response to a file
   # param  string  optional: custom filename
   function http.responseExport(){
@@ -441,14 +502,17 @@ EOH
     fi
   }
 
-  # import a former response from a file
+  # ......................................................................
+  #
+  # Import a former response from a file
+  #
+  # param  string  filename with stored response
   function http.responseImport(){
     http._wd "${FUNCNAME[0]}($1)"
     local infile
     infile=$(http._genOutfilename "$1")
     if [ -r "${infile}" ]; then
-      grep "^#_META_|about:$http_cfg__about" "${infile}" >/dev/null
-      if [ $? -eq 0 ]; then
+      if grep -q "^#_META_|about:$http_cfg__about" "${infile}"; then
          http_resp__neutral=$(cat "${infile}")
       else
          echo "ERROR: Ooops [${infile}] does not seem to be an export dump."
@@ -459,17 +523,20 @@ EOH
       http.quit
     fi
   }
-  # delete an exported file; this is especially useful if you use
+
+  # ......................................................................
+  #
+  # Delete an exported file; this is especially useful if you use
   # AUTOFILE functionality
+  #
+  # param  string  filename with stored response
   function http.responseDelete(){
     http._wd "${FUNCNAME[0]}($1)"
     local infile
     infile=$(http._genOutfilename "$1")
     if [ -r "${infile}" ]; then
-      grep "^#_META_|about:$http_cfg__about" "${infile}" >/dev/null
-      if [ $? -eq 0 ]; then
-        rm -f "${infile}"
-        if [ $? -eq 0 ]; then
+      if grep -q "^#_META_|about:$http_cfg__about" "${infile}"; then
+        if rm -f "${infile}"; then
           http._wd "OK, ${infile} was deleted."
         else
           http._wd "ERROR: unable to delete existing ${infile}. Check permissions."
@@ -486,31 +553,85 @@ EOH
   # SETTER
   # ======================================================================
 
-  # set authentication
+  # ......................................................................
+  #
+  # Add a line to the request header
+  #
+  # param  string  line to add, eg "Connection: keep-alive"
+  function http.addHeader(){
+    http._wd "${FUNCNAME[0]}($1)"
+    http_req__headers+=( -H "$1")
+  }
+
+  # ......................................................................
+  #
+  # set Accept request header and override default
+  #
+  # param  string  accept header value, eg text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+  function http.setAccept(){
+    http._wd "${FUNCNAME[0]}($1)"
+    if [ -z "$1" ]; then
+      http_req__accept=
+    else
+      http_req__accept="$1"
+    fi
+  }
+
+  # ......................................................................
+  #
+  # Set basic authentication
+  #
   # param  string  USER:PASSWORD
   function http.setAuth(){
     http._wd "${FUNCNAME[0]}($1)"
     if [ -z "$1" ]; then
       http_req__auth=
     else
-      http_req__auth="-u $1"
+      http_req__auth="$1"
+    fi
+  }
+
+  # ......................................................................
+  #
+  # Set authentication via Athorization header
+  #
+  # param  string  type, eg. Basic|Bearer|Negotiate
+  # param  string  token or encoded user + password
+  function http.setAuthorization(){
+    http._wd "${FUNCNAME[0]}($1 $2)"
+    if [ -z "$1" ]; then
+      http_req__authorization=
+    else
+      http_req__authorization="${1} ${2}"
     fi
   }
-  # set body to send for PUTs and POSTs
+
+  # ......................................................................
+  #
+  # Set body to send for PUTs and POSTs
+  #
   # param  string  body
   function http.setBody(){
     http._wd "${FUNCNAME[0]}($1)"
     http_req__body=$1
   }
-  # set a base url of an API
+
+  # ......................................................................
+  #
+  # Set a base url of an API
   # Remark: Then use http.setUrl to complet the url to request
+  #
   # param  string  url
   function http.setBaseUrl(){
     http._wd "${FUNCNAME[0]}($1)"
     http_req__baseurl=$1
     http.setFullUrl ""
   }
+
+  # ......................................................................
+  #
   # Enable or disable debug mode
+  #
   # param  integer  0|1
   function http.setDebug(){
     http._wd "${FUNCNAME[0]}($1)"
@@ -521,14 +642,20 @@ EOH
     http_req__docs=$1
   }
 
-  # set the method to use; GET|POST|PUT|DELETE
+  # ......................................................................
+  #
+  # Set the method to use; GET|POST|PUT|DELETE|...
+  #
   # param  string  name of method
   function http.setMethod(){
     http._wd "${FUNCNAME[0]}($1)"
     http_req__method=$1
   }
 
-  # set a full url to request
+  # ......................................................................
+  #
+  # Set a full url to request
+  #
   # param  string  optional: url
   function http.setFullUrl(){
     http._wd "${FUNCNAME[0]}($1)"
@@ -538,7 +665,11 @@ EOH
       http_req__fullurl=$1
     fi
   }
-  # complete the base url
+
+  # ......................................................................
+  #
+  # Complete the base url
+  #
   # param  string  url part behind base url
   function http.setUrl(){
     http._wd "${FUNCNAME[0]}($1)"
@@ -548,16 +679,29 @@ EOH
 
   # ----- caching
 
+  # ......................................................................
+  #
+  # Set cache ttl in seconds
+  #
+  # param  integer  ttl in seconds
   function http.setCacheTtl(){
     http._wd "${FUNCNAME[0]}($1)"
     http_cfg__cacheTtl=$1
   }
 
+  # ......................................................................
+  #
+  # Set cache file
+  #
+  # param  string  filename
   function http.setCacheFile(){
     http._wd "${FUNCNAME[0]}($1)"
     http_cfg__cacheFile="$1"
   }
 
+  # ......................................................................
+  #
+  # Flush the cache  
   function http.flushCache(){
     http._wd "${FUNCNAME[0]}($1)"
     rm -f ${http_cfg__cacheDir}/*
@@ -574,7 +718,8 @@ $http_cfg__about
 
 This is a bash solution to script REST API calls.
 
-Source:$http_cfg__prjurl
+Source: <$http_cfg__prjurl>
+Docs: <$http_cfg__docsurl>
 License: GNU GPL 3
 
 
@@ -593,8 +738,17 @@ INSTRUCTION:
 
 - initialize a request
 
+    setAccept ACCEPT
+      Set authentication with user and password for basic auth
+      Default: $http_req__accept
+
     setAuth AUTH:PASSWORD
-      set authentication
+      Set authentication with user and password for basic auth
+
+    setAuthorization TYPE TOKEN|HASH
+      Set authentication with Authorization header. 
+      As TYPE you can use Basic|Bearer|Negotiate|...
+      2nd param is the token or hased user+password
 
     http.setBody DATA
       set a body for POST/ PUT requests.
@@ -616,6 +770,10 @@ INSTRUCTION:
       Set a relative url for a request.
       This requires to use http.setBaseUrl before.
 
+    http.addHeader HEADER_LINE
+      Add a header line to the request.
+      This command can be repeated multiple times.
+
 - caching functions
 
     http.setCacheTtl SECONDS
diff --git a/tests/color.class.sh b/tests/color.class.sh
new file mode 100644
index 0000000000000000000000000000000000000000..362078205343127eac90576b64e96e9aca4cd3e9
--- /dev/null
+++ b/tests/color.class.sh
@@ -0,0 +1,601 @@
+#!/bin/bash
+# ======================================================================
+#
+# COLORS
+#
+# a few shell functions for colored output
+# 
+# ----------------------------------------------------------------------
+# License: GPL 3.0
+# Source: <https://github.com/axelhahn/bash_colorfunctions>
+# Docs: <https://www.axel-hahn.de/docs/bash_colorfunctions/>
+# ----------------------------------------------------------------------
+# 2023-08-09  ahahn  0.1  initial lines
+# 2023-08-09  ahahn  0.2  hide output of regex test with grep
+# 2023-08-13  ahahn  0.3  introduce of color presets with foreground and background
+# 2023-08-13  ahahn  0.4  list presets, debug, count of colors
+# 2023-08-13  ahahn  0.5  support of RGB hex code
+# 2023-08-14  ahahn  0.6  fix setting fg and bg as RGB hex code
+# 2023-08-14  ahahn  0.7  remove color.ansi; respect NO_COLOR=1
+# 2023-08-16  ahahn  0.8  add function color.preset
+# ======================================================================
+
+_VERSION=0.8
+typeset -i COLOR_DEBUG; COLOR_DEBUG=0
+
+# ----------------------------------------------------------------------
+# CONSTANTS
+# ----------------------------------------------------------------------
+
+declare -A BGCOLOR_CODE
+declare -A COLOR_CODE
+
+# background colors
+BGCOLOR_CODE[black]="40"
+BGCOLOR_CODE[red]="41"
+BGCOLOR_CODE[green]="42"
+BGCOLOR_CODE[brown]="43"
+BGCOLOR_CODE[blue]="44"
+BGCOLOR_CODE[purple]="45"
+BGCOLOR_CODE[cyan]="46"
+BGCOLOR_CODE[lightgray]="47"
+BGCOLOR_CODE[darkgray]="1;40"
+BGCOLOR_CODE[lightred]="1;41"
+BGCOLOR_CODE[lightgreen]="1;42"
+BGCOLOR_CODE[yellow]="1;43"
+BGCOLOR_CODE[lightblue]="1;44"
+BGCOLOR_CODE[lightpurple]="1;45"
+BGCOLOR_CODE[lightcyan]="1;46"
+BGCOLOR_CODE[white]="1;47"
+
+# foreground colors
+COLOR_CODE[black]="30"
+COLOR_CODE[red]="31"
+COLOR_CODE[green]="32"
+COLOR_CODE[brown]="33"
+COLOR_CODE[blue]="34"
+COLOR_CODE[purple]="35"
+COLOR_CODE[cyan]="36"
+COLOR_CODE[lightgray]="37"
+COLOR_CODE[darkgray]="1;30"
+COLOR_CODE[lightred]="1;31"
+COLOR_CODE[lightgreen]="1;32"
+COLOR_CODE[yellow]="1;33"
+COLOR_CODE[lightblue]="1;34"
+COLOR_CODE[lightpurple]="1;35"
+COLOR_CODE[lightcyan]="1;36"
+COLOR_CODE[white]="1;37"
+
+# custom presets as array of foreground and background color
+#
+#              +--- the label is part of the variable
+#              |
+#              v
+# COLOR_PRESET_error=("white" "red")
+# COLOR_PRESET_ok=("white" "green")
+
+# ----------------------------------------------------------------------
+# PRIVATE FUNCTIONS
+# ----------------------------------------------------------------------
+
+# write debug output - if debugging is enabled
+# Its output is written to STDERR
+# param  string  text to show
+function color.__wd(){
+    test "$COLOR_DEBUG" = "1" && >&2 echo "DEBUG: $*"
+}
+
+# test, if given value is a known color name
+# param  string  colorname to test
+function color.__iscolorname(){
+    test -n "${COLOR_CODE[$1]}" && return 0
+    return 1
+}
+
+# test, if given value is a value 0..7
+# param  string  color to test
+function color.__iscolorcode(){
+    test "$1" = "0" && return 0
+    test "$1" = "1" && return 0
+    test "$1" = "2" && return 0
+    test "$1" = "3" && return 0
+    test "$1" = "4" && return 0
+    test "$1" = "5" && return 0
+    test "$1" = "6" && return 0
+    test "$1" = "7" && return 0
+    return 1
+}
+
+# test, if given value is an ansi code
+# param  string  color to test
+function color.__iscolorvalue(){
+    if grep -E "^([01];|)[34][0-7]$" >/dev/null <<< "$1" ; then
+        return 0
+    fi
+    return 1
+}
+
+# test, if given value is an rgb hexcode eg. #80a0f0
+# param  string  color to test
+function color.__isrgbhex(){
+    if grep -iE "^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$" >/dev/null <<< "$1" ; then
+        return 0
+    fi
+    return 1
+}
+
+# convert rgb hex code eg. #80a0f0 to 3 decimal values
+# output us a string with space separated values for red, green, blue
+# param  string  color as "#RRGGBB" to convert
+function color.__getrgb(){
+    local _r
+    local _g
+    local _b
+    if color.__isrgbhex "$1"; then
+        _r=$( cut -c 2,3 <<< "$1" )
+        _g=$( cut -c 4,5 <<< "$1" )
+        _b=$( cut -c 6,7 <<< "$1" )
+        echo "$((16#$_r)) $((16#$_g)) $((16#$_b))"
+    fi
+}
+
+# test, if given value is a color that can be one of
+# - colorname
+# - value 0..7
+# - ansi code
+# param  string  color to test
+function color.__isacolor(){
+    if color.__iscolorname "$1"; then return 0; fi
+    if color.__iscolorcode "$1"; then return 0; fi
+    if color.__iscolorvalue "$1"; then return 0; fi
+    if color.__isrgbhex "$1"; then return 0; fi
+    color.__wd "$FUNCNAME is acolor: $1 --> No"
+    return 1
+}
+
+# test, if given value is an existing preset
+# param  string  color to test
+function color.__isapreset(){
+    local _colorset
+    eval "_colorset=\$COLOR_PRESET_${1}" 
+    test -n "$_colorset" && return 0
+    return 1
+}
+
+# respect NO_COLOR=1
+# return 1 if colors are allowed to be used.
+function color.__usecolor(){
+    test "$NO_COLOR" = "1" && return 1
+    return 0
+}
+
+# set foreground or background
+# param  string  color as
+#                - basic color 0..7 OR 
+#                - color name eg. "black" OR 
+#                - a valid color value eg. "1;30" OR 
+#                - a hex code eg. "#10404f"
+# param  integer what to set; '3' for for foreground or '4' for background colors
+function color.__fgorbg(){
+    local _color="$1"
+    local _prefix="$2"
+    color.__wd "$FUNCNAME $1 $2"
+    if color.__iscolorname "${_color}"; then
+        color.__wd "yep, ${_color} is a color name."
+        test "$_prefix" = "3" && color.set "${COLOR_CODE[${_color}]}"
+        test "$_prefix" = "4" && color.set "${BGCOLOR_CODE[${_color}]}"
+    else
+        if color.__iscolorcode "${_color}"; then
+            color.__wd "yep, ${_color} is a color code."
+        else
+            if color.__iscolorvalue "${_color}"; then
+                color.__wd "yep, ${_color} is a color value."
+                color.set "${_color}"
+            else
+                if color.__isrgbhex "${_color}"; then
+                    local _r
+                    local _g
+                    local _b
+                    read -r _r _g _b <<< $( color.__getrgb "${_color}" )
+                    color.set "${_prefix}8;2;$_r;$_g;$_b"
+                else
+                    >&2 echo "ERROR: color '${_color}' is not a name nor a value between 0..7 nor a valid color value nor RGB."
+                fi
+            fi
+        fi
+    fi
+}
+
+# ----------------------------------------------------------------------
+# FUNCTIONS :: helpers
+# ----------------------------------------------------------------------
+
+# get count of colors in the current terminal
+function color.count(){
+    tput colors
+}
+
+# enable debug flag
+function color.debugon(){
+    COLOR_DEBUG=1
+    color.__wd "$FUNCNAME - debugging is enabled now"
+}
+
+# disable debug flag
+function color.debugoff(){
+    color.__wd "$FUNCNAME - disabling debugging now"
+    COLOR_DEBUG=0
+}
+
+# show debugging status
+function color.debugstatus(){
+    echo -n "INFO: color.debug - debugging is "
+    if [ $COLOR_DEBUG -eq 0 ]; then
+        echo "DISABLED"
+    else
+        echo "ENABLED"
+    fi
+}
+
+# show help
+function color.help(){
+    local _self; _self='[path]/color.class.sh'
+    color.reset
+    local _debug=$COLOR_DEBUG
+    COLOR_DEBUG=0
+
+    echo "_______________________________________________________________________________"
+    echo
+    color.echo "red"      "   ###   ###  #      ###  ####"
+    color.echo "yellow"   "  #     #   # #     #   # #   #"
+    color.echo "white"    "  #     #   # #     #   # ####"
+    color.echo "yellow"   "  #     #   # #     #   # #  #"
+    color.echo "red"      "   ###   ###  #####  ###  #   #"
+    echo "_________________________________________________________________________/ v$_VERSION"
+    echo
+
+    sed "s#^    ##g" << EOH
+    HELP:
+      'color' is a class like component to simplify the handling of ansi colors and keeps
+      the color settings readable. A set NO_COLOR=1 will be respected.
+
+      Author: Axel Hahn
+      License: GNU GPL 3.0
+      Source: <https://github.com/axelhahn/bash_colorfunctions>
+      Docs: <https://www.axel-hahn.de/docs/bash_colorfunctions/>
+
+
+    FUNCTIONS:
+
+      ---------- Information:
+
+      color.help       this help
+      color.list       show a table with valid color names
+      color.presets    show a table with defined custom presets
+
+      color.count      get count of colors in the current terminal
+
+      color.debugon    enable debugging
+      color.debugoff   disable debugging
+      color.debugstatus  show debugstatus
+
+      ---------- Colored output:
+
+      color.bg COLOR (COLOR2)
+                       set a background color; a 2nd parameter is optional to set
+                       a foreground color too
+      color.fg COLOR (COLOR2)
+                       set a foreground color; a 2nd parameter is optional to set
+                       a background color too
+      color.preset PRESET
+                       Apply the color set of foreground and background of a given 
+                       preset name.
+      color.echo COLOR|PRESET (COLOR2) TEXT
+                       write a colored text with carriage return and reset colors
+                       The 1st param must be a COLOR(code/ name) for the 
+                       foreground or a label of a preset.
+                       The 2nd CAN be a color for the background, but can be 
+                       skipped.
+                       Everything behind is text for the output.
+      color.print COLOR|PRESET (COLOR2) TEXT
+                       see color.echo - the same but without carriage return.
+      color.reset      reset colors
+      color.set RAWCOLOR (RAWCOLOR2 (... RAWCOLOR_N))
+                       set ansi colors; it can handle multiple color values
+
+
+      ---------- Other:
+
+      color.blink      start blinking text
+      color.bold       start bold text
+      color.invert     start inverted text
+      color.underline  start underline text
+
+    VALUES:
+      COLOR            a color; it can be...
+                       - a color keyword, eg black, blue, red, ... for all
+                         known values run 'color.list'
+                       - a value 0..7 to set basic colors 30..37 (or 40..47)
+                       - an ansi color value eg. "30" or "1;42"
+                       - RGB hexcode with '#' as prefix followed by 2 digit 
+                         hexcode for red, green and blue eg. "#10404f" 
+                         (like css rgb color codes)
+      PRESET           Name of a custom preset; see DEFINE PRESETS below.
+      RAWCOLOR         an ansi color value eg. "30" (black foreground) or 
+                       "1;42" (lightgreen background)
+
+
+    DEFINE PRESETS:
+      A shortcut for a combination of foreground + background color. The label
+      is part of a bash variable with the prefix 'COLOR_PRESET_'.
+      The value is a bash array with 2 colors for foreground and background. 
+      See the value description for COLOR above.
+
+      SYNTAX:
+      COLOR_PRESET_<LABEL>=(<FOREGROUND> <BACKGROUND>)
+
+      To see all defined presets use 'color.presets'
+
+
+    EXAMPLES:
+      First you need to source the file $_self.
+      . $_self
+
+      (1)
+      Show output of the command 'ls -l' in blue
+        color.fg "blue"
+        ls -l
+        color.reset
+
+      (2)
+      show a red error message
+        color.echo "red" "ERROR: Something went wrong."
+
+      (3)
+      Use a custom preset:
+        COLOR_PRESET_error=("white" "red")
+        color.echo "error" "ERROR: Something went wrong."
+
+      This defines a preset named "error". "white" is a colorname
+      for the foreground color, "red" ist the background.
+
+EOH
+
+    if [ -n "$NO_COLOR" ]; then
+        echo -n "INFO: NO_COLOR=$NO_COLOR was set. The coloring functionality is "
+        if ! color.__usecolor; then
+            echo "DISBALED."
+        else
+            echo "ENABLED (must be 1 to disable)."
+        fi
+        echo
+    else
+        echo "INFO: NO_COLOR will be respected - but it is not set."
+    fi
+
+    COLOR_DEBUG=$_debug
+}
+
+# a little helper: show colors and the color codes
+function color.list(){
+    color.reset
+    local _debug=$COLOR_DEBUG
+    COLOR_DEBUG=0
+
+    echo
+    echo "List of colors:"
+    echo
+
+    echo "--------------------------------------------------"
+    echo "color          | foreground         | background"
+    echo "--------------------------------------------------"
+    for i in "${!COLOR_CODE[@]}"
+    do
+        printf "%-15s %4s " $i ${COLOR_CODE[$i]} 
+        color.set "${COLOR_CODE[$i]}"
+        color.set "40"
+        printf " Test "
+
+        color.set "1;47"
+        color.set "${COLOR_CODE[$i]}"
+        printf " Test "
+        color.reset
+
+        printf "   %5s " ${BGCOLOR_CODE[$i]} 
+        color.set ${BGCOLOR_CODE[$i]}
+        printf " Test "
+        color.reset
+        echo
+
+    done | sort
+    color.reset
+    echo "--------------------------------------------------"
+    echo
+    COLOR_DEBUG=$_debug
+}
+
+# little helper: sow defined presets and its preview
+function color.presets(){
+    local _label
+    local _value
+    local _colorvar
+    local _fg
+    local _bg
+
+    color.reset
+    local _debug=$COLOR_DEBUG
+    COLOR_DEBUG=0
+
+    if ! set | grep "^COLOR_PRESET_.*=(" >/dev/null; then
+        echo "INFO: No preset was defined yet."
+        echo "To set one define shell variables with an array of 2 colors:"
+        echo "  COLOR_PRESET_<LABEL>=(<FOREGROUND> <BACKGROUND>)"
+        echo "For more help call 'color.help' or see the docs."
+    else
+        echo
+        echo "List of presets:"
+        echo
+        echo "---------------------------------------------------------------------"
+        echo "label      | foreground   | background   | example"
+        echo "---------------------------------------------------------------------"
+
+        set | grep "^COLOR_PRESET_.*=(" | while read -r line
+        do
+            _label=$( cut -f 1 -d '=' <<< "$line" | cut -f 3- -d '_')
+            _example=$( color.print "$_label" "example for peset '$_label'" )
+            _colorvar="COLOR_PRESET_${_label}" 
+            eval "_fg=\${$_colorvar[0]}"
+            eval "_bg=\${$_colorvar[1]}"
+
+            printf "%-10s | %-12s | %-12s | %-50s\n"  "$_label" "${_fg}" "${_bg}" "$_example"
+        done
+        echo "---------------------------------------------------------------------"
+        echo
+    fi
+    COLOR_DEBUG=$_debug
+}
+# ----------------------------------------------------------------------
+# FUNCTIONS :: set color
+# ----------------------------------------------------------------------
+
+# set background color
+# param  string  backround color 0..7 OR color name eg "black" or a valid color value eg "1;30"
+# param  string  optional: foreground color
+function color.bg(){
+    color.__wd "$FUNCNAME $1"
+    color.__fgorbg "$1" 4
+    test -n "$2" && color.fg "$2"
+}
+
+# get a color of a preset
+# param  string   name of preset
+# param  integer  array index; 0= foreground; 1= background
+function color.__getpresetcolor(){
+    local _label=$1
+    local _index=$2
+    local _colorvar
+    _colorvar="COLOR_PRESET_${_label}" 
+    eval "echo \${$_colorvar[$_index]}"
+}
+
+# set foreground color
+# param  string  foreground color 0..7 OR color name eg "black" or a valid color value eg "1;30"
+# param  string  optional: background color
+function color.fg(){
+    color.__wd "$FUNCNAME $1"
+    color.__fgorbg "$1" 3
+    test -n "$2" && color.bg "$2"
+}
+
+
+# set colors of a preset
+# param  string  label of a preet
+function color.preset(){
+    if color.__isapreset "$1"; then
+        local _colorvar
+        local _colfg=$( color.__getpresetcolor "$1" 0)
+        local _colbg=$( color.__getpresetcolor "$1" 1)
+        color.reset
+        test -n "$_colfg" && color.__fgorbg "$_colfg" 3
+        test -n "$_colbg" && color.__fgorbg "$_colbg" 4
+    else
+        >&2 echo "ERROR: this value is not a valid preset: $1. See 'color.presets' to see current presets."
+    fi
+}
+
+# ----------------------------------------------------------------------
+
+# reset all colors to terminal default
+function color.reset(){
+    color.__wd "$FUNCNAME"
+    color.set "0"
+}
+
+# start bold text
+function color.bold(){
+    color.__wd "$FUNCNAME"
+    color.set "1"
+}
+
+# start underline text
+function color.underline(){
+    color.__wd "$FUNCNAME"
+    color.set "4"
+}
+
+# start blinking text
+function color.blink(){
+    color.__wd "$FUNCNAME"
+    color.set "5"
+}
+
+# start inverted text
+function color.invert(){
+    color.__wd "$FUNCNAME"
+    color.set "7"
+}
+
+# ----------------------------------------------------------------------
+
+# write ansicode to set color combination
+# param  string  color 1 as ansi value
+# param  string  color N as ansi value
+function color.set(){
+    local _out=
+    if color.__usecolor; then
+        for mycolor in $*
+        do
+            color.__wd "$FUNCNAME: processing color value '${mycolor}'"
+            _out+="${mycolor}"
+        done
+        color.__wd "$FUNCNAME: output is '\e[${_out}m'"
+        printf "\e[${_out}m"
+    else
+        color.__wd "$FUNCNAME: skipping - coloring is disabled."
+    fi
+}
+
+# ----------------------------------------------------------------------
+# FUNCTIONS :: print
+# ----------------------------------------------------------------------
+
+# show a colored text WITH carriage return
+# param  string  foreground color as code / name / value
+# param  string  optional: background color as code / name / value
+# param  string  text to print
+function color.echo(){
+    color.__wd "$FUNCNAME $*"
+    local _param1="$1"
+    local _param2="$2"
+    shift 1
+    shift 1
+    color.print "$_param1" "$_param2" "$*"
+    echo
+}
+
+# show a colored text without carriage return
+# param  string  foreground color as code / name / value or preset
+# param  string  optional: background color as code / name / value
+# param  string  text to print
+function color.print(){
+    color.__wd "$FUNCNAME $*"
+    if color.__isacolor "$1"; then
+        if color.__isacolor "$2"; then
+            color.fg "$1" "$2"
+            shift 1
+            shift 1
+        else
+            color.fg "$1"
+            shift 1
+        fi
+    elif color.__isapreset "$1"; then
+        color.preset "$1"
+        shift 1
+    else
+        >&2 echo -n "ERROR: Wrong color values detected. Command was: colors.print $*"
+    fi
+    echo -n "$*"
+    color.reset
+}
+
+# ======================================================================
diff --git a/tests/example_01_simple_get.sh b/tests/example_01_simple_get.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4943e6c5decf841b1439ba861459766a2711fbb8
--- /dev/null
+++ b/tests/example_01_simple_get.sh
@@ -0,0 +1,101 @@
+#!/bin/bash
+# ======================================================================
+#
+# REST API CLIENT
+#
+# Example 1 :: Simple GET request
+# This is an introduction, how it works.
+#
+# ======================================================================
+
+cd "$( dirname "$0" )" || exit
+
+# shellcheck source=../rest-api-client.sh
+. ../rest-api-client.sh
+
+# shellcheck source=color.class.sh
+. color.class.sh
+
+sURL="http://www.iml.unibe.ch/"
+
+# ----------------------------------------------------------------------
+# FUNCTIONS
+# ----------------------------------------------------------------------
+
+function wait4Return(){
+
+    local _sleep
+    _sleep=${1:-10} # default 10
+    echo
+    echo
+    color.print "cyan" "Press return to continue or wait $_sleep seconds ... "
+    read -r -s -t $_sleep dummy
+    echo
+    echo
+    echo
+}
+
+
+# ----------------------------------------------------------------------
+# MAIN
+# ----------------------------------------------------------------------
+
+color.fg "yellow"
+cat <<EOH
+----------------------------------------------------------------------
+
+Example 1 :: Simple GET request
+This is a introduction, how it works.
+
+----------------------------------------------------------------------
+
+EOH
+color.reset
+
+
+echo "We need to initialize the client with 'http.init' before each new request."
+echo
+color.echo "green" "> http.init"
+http.init
+
+wait4Return 10
+
+echo "Let's make a GET request to our example url $sURL."
+echo
+color.echo "green" "> http.makeRequest GET '$sURL'"
+http.makeRequest GET "$sURL"
+echo "Done."
+echo "Here is no output."
+echo "Now we can read information from the response."
+
+wait4Return 10
+
+color.echo "green" "> http.getStatuscode - This returns the Http status code"
+http.getStatuscode
+echo
+sleep 1
+
+color.echo "green" "> http.getStatus - You get the Status as string OK|Redirect|Error"
+http.getStatus
+echo
+sleep 1
+
+color.echo "green" "> http.getResponseHeader - print Http response header"
+http.getResponseHeader
+echo
+sleep 1
+
+color.echo "green" "> http.getResponseData - get data from curl"
+http.getResponseData
+echo
+sleep 1
+
+color.echo "green" "> http.getResponse - get response body"
+http.getResponse
+echo
+sleep 1
+
+echo
+echo "That's all for the moment. Bye."
+
+# ----------------------------------------------------------------------
\ No newline at end of file