diff --git a/public_html/api/index.php b/public_html/api/index.php
index 31063b5ec3020186b873c77161bc7b24198e886a..15c0b25ad5c8cb4889cc86851f94ec17d18d976b 100644
--- a/public_html/api/index.php
+++ b/public_html/api/index.php
@@ -11,245 +11,271 @@
  * ----------------------------------------------------------------------
  * 2020-06-16  v0.9  <axel.hahn@iml.unibe.ch>  
  * 2021-03-29  v1.2  <axel.hahn@iml.unibe.ch>  support slashes in branch names
+ * 2024-09-02  v1.3  <axel.hahn@unibe.ch>      php8 only; added variable types; short array syntax
  * ======================================================================
  */
 
-    $bDebug=false;
-    ini_set('display_errors', 1);
-    ini_set('display_startup_errors', 1);
-    error_reporting(E_ALL);
-
-    require_once("../../config/inc_projects_config.php");
-    
-    $sDirClasses=__DIR__.'/../deployment/classes/';
-    require_once($sDirClasses.'/project.class.php');
-    require_once($sDirClasses.'logger.class.php');
-
-    $iMaxAge=60;
-    
-    // ----------------------------------------------------------------------
-    // FUNCTIONS
-    // ----------------------------------------------------------------------
-    /**
-     * write debug text (if enabled)
-     * @global boolean $bDebug
-     * @param string  $s       message
-     * @param string  $sLevel  level; one of info|
-     * @return boolean
-     */
-    function _wd($s, $sLevel='info'){
-        global $bDebug;
-        if ($bDebug){
-            echo '<div class="debug debug-'.$sLevel.'">DEBUG: '.$s.'</div>';
-        }
-        return true;
+$bDebug = false;
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
+
+/**
+ * Path to deployment classes
+ * @var string
+ */
+ $sDirClasses = __DIR__ . '/../deployment/classes/';
+
+ /**
+ * Allowed time delta for client or server
+ * @var integer
+ */
+$iMaxAge = 60;
+
+require_once("../../config/inc_projects_config.php");
+
+require_once($sDirClasses . '/project.class.php');
+require_once($sDirClasses . 'logger.class.php');
+
+// ----------------------------------------------------------------------
+// FUNCTIONS
+// ----------------------------------------------------------------------
+/**
+ * Write debug text (if enabled)
+ * 
+ * @global boolean $bDebug
+ * 
+ * @param string  $s       message
+ * @param string  $sLevel  level; one of info|
+ * @return boolean
+ */
+function _wd(string $s, string $sLevel = 'info'): bool
+{
+    global $bDebug;
+    if ($bDebug) {
+        echo "<div class=\"debug debug-$sLevel\">DEBUG: $s</div>";
     }
-    
-    /**
-     * abort execution with error
-     * @param string   $s        message
-     * @param integer  $iStatus  http status code to send
-     */
-    function _quit($s, $iStatus=400){
-        $aStatus=array(
-           400=>'HTTP/1.0 400 Bad Request', 
-           403=>'HTTP/1.0 403 Access denied', 
-           404=>'HTTP/1.0 404 Not found', 
-        );
-        header($aStatus[$iStatus]);
-        _done(array('status'=>$iStatus, 'info'=>$aStatus[$iStatus], 'message'=>$s));
+    return true;
+}
+
+/**
+ * Abort execution of API requestwith error
+ * 
+ * @param string   $s        message
+ * @param integer  $iStatus  http status code to send
+ */
+function _quit(string $s, int $iStatus = 400): void
+{
+    $aStatus = [
+        400 => 'HTTP/1.0 400 Bad Request',
+        403 => 'HTTP/1.0 403 Access denied',
+        404 => 'HTTP/1.0 404 Not found',
+    ];
+    header($aStatus[$iStatus]);
+    _done(['status' => $iStatus, 'info' => $aStatus[$iStatus], 'message' => $s]);
+}
+
+/**
+ * End with OK output
+ * 
+ * @param array $Data  array data to show as JSON
+ * @return void
+ */
+function _done(array $Data): void
+{
+    echo is_array($Data)
+        ? json_encode($Data, JSON_PRETTY_PRINT)
+        : $Data
+    ;
+    die();
+}
+
+/**
+ * Check authorization in the http request header and age of timestamp
+ * On a failed check the request will be terminated
+ * 
+ * @global int $iMaxAge         max allowed age
+ * 
+ * @param string $sProjectSecret
+ * @return boolean
+ */
+function _checkAuth(string $sProjectSecret): bool
+{
+    global $iMaxAge;
+    $aReqHeaders = apache_request_headers();
+    _wd('<pre>' . print_r($aReqHeaders, 1) . '</pre>');
+    if (!isset($aReqHeaders['Authorization'])) {
+        _quit('Access denied. Missing authorization.', 403);
     }
-    /**
-     * end with OK output
-     * @param type $Data
-     */
-    function _done($Data){
-        echo is_array($Data) 
-            ? json_encode($Data, JSON_PRETTY_PRINT)
-            : $Data
-            ;
-        die();
+    if (!isset($aReqHeaders['Date'])) {
+        _quit('Access denied. Missing field "Date:" in the request header.', 403);
     }
-    
-    /**
-     * Check authorization in the http request header and age of timestamp
-     * On a failed check the request will be terminated
-     * @global int $iMaxAge         max allowed age
-     * @param string $sProjectSecret
-     * @return boolean
-     */
-    function _checkAuth($sProjectSecret){
-        global $iMaxAge;
-        $aReqHeaders=apache_request_headers();
-        _wd('<pre>'.print_r($aReqHeaders, 1).'</pre>');
-        if(!isset($aReqHeaders['Authorization'])){
-            _quit('Access denied. Missing authorization.', 403);
-        }         
-        if(!isset($aReqHeaders['Date'])){
-            _quit('Access denied. Missing field "Date:" in the request header.', 403);
-        }         
-
-        $sGotHash= preg_replace('/^.*\:/', '', $aReqHeaders['Authorization']);
-        $sGotDate= $aReqHeaders['Date'];
-        $sGotMethod=$_SERVER['REQUEST_METHOD'];
-        $sGotReq=$_SERVER['REQUEST_URI'];
-
-
-        $sMyData="$sGotMethod\n$sGotReq\n$sGotDate\n";
-        $sMyHash= base64_encode(hash_hmac("sha1", $sMyData, $sProjectSecret));
-
-        _wd('Hash: '.$sGotHash.' -- from header');
-        _wd('Hash: '.$sMyHash.' -- rebuilt');
-        if($sGotHash!==$sMyHash){
-            _quit('Access denied. Invalid hash.', 403);
-        }
 
-        $iAge=date('U')-date('U', strtotime($sGotDate));
-        _wd('Date: '.$sGotDate.' - age: '.$iAge.' sec');
-        if($iAge>$iMaxAge){
-            _quit('Access denied. Hash is out of date: '.$iAge. ' sec is older '.$iMaxAge.' sec. Maybe client or server is out of sync.', 403);
-        }
-        if($iAge<-$iMaxAge){
-            _quit('Access denied. Hash is '.$iAge. ' sec in future but only '.$iMaxAge.' sec are allowed. Maybe client or server is out of sync.', 403);
-        }
-        return true;
+    $sGotHash = preg_replace('/^.*\:/', '', $aReqHeaders['Authorization']);
+    $sGotDate = $aReqHeaders['Date'];
+    $sGotMethod = $_SERVER['REQUEST_METHOD'];
+    $sGotReq = $_SERVER['REQUEST_URI'];
+
+
+    $sMyData = "$sGotMethod\n$sGotReq\n$sGotDate\n";
+    $sMyHash = base64_encode(hash_hmac("sha1", $sMyData, $sProjectSecret));
+
+    _wd('Hash: ' . $sGotHash . ' -- from header');
+    _wd('Hash: ' . $sMyHash . ' -- rebuilt');
+    if ($sGotHash !== $sMyHash) {
+        _quit('Access denied. Invalid hash.', 403);
+    }
+
+    $iAge = date('U') - date('U', strtotime($sGotDate));
+    _wd('Date: ' . $sGotDate . ' - age: ' . $iAge . ' sec');
+    if ($iAge > $iMaxAge) {
+        _quit('Access denied. Hash is out of date: ' . $iAge . ' sec is older ' . $iMaxAge . ' sec. Maybe client or server is out of sync.', 403);
     }
-    // ----------------------------------------------------------------------
-    // MAIN
-    // ----------------------------------------------------------------------
-    if (!$bDebug){
-        header('Content-Type: application/json');
+    if ($iAge < -$iMaxAge) {
+        _quit('Access denied. Hash is ' . $iAge . ' sec in future but only ' . $iMaxAge . ' sec are allowed. Maybe client or server is out of sync.', 403);
     }
-    _wd('Start: '.date('Y-m-d H:i:s').'<style>body{background:#eee; color:#456;}
+    return true;
+}
+// ----------------------------------------------------------------------
+// MAIN
+// ----------------------------------------------------------------------
+if (!$bDebug) {
+    header('Content-Type: application/json');
+}
+_wd('Start: ' . date('Y-m-d H:i:s') . '<style>body{background:#eee; color:#456;}
             .debug{background:#ddd; margin-bottom: 2px;}
          </style>');
 
-    _wd('request uri is '.$_SERVER["REQUEST_URI"]); 
-    _wd('<pre>GET: '.print_r($_GET, 1).'</pre>');
-
-    
-    // ---------- SPLIT URL
-    
-    $aUriSplit= explode('/', preg_replace('/\?.*$/', '', $_SERVER["REQUEST_URI"]));
-
-    array_shift($aUriSplit);
-    array_shift($aUriSplit);
-    _wd('<pre>$aUriSplit: '.print_r($aUriSplit, 1).'</pre>');  
-    /*
-    
-    /api/v1/projects/ci/build/...
-    $aUriSplit: Array
-        (
-            [0] => v1
-            [1] => projects
-            [2] => ci
-            [3] => build
-        )
-     */
-    $sApiVersion = isset($aUriSplit[0]) ? $aUriSplit[0] : false;
-    $sApiItem    = isset($aUriSplit[1]) ? $aUriSplit[1] : false;
-
-
-    if(!$sApiVersion){
-        _quit('ERROR: no param for api version was found.');
-    }
-    if(!$sApiItem){
-        _quit('ERROR: no param for item was found.');
-    }
-    
-    
-    switch ($sApiVersion){
-        case 'v1':
-            switch($sApiItem){
-                case 'projects':
-
-                    $oProject=new project();
-                    $aList=$oProject->getProjects();
-                    _wd('<pre>'.print_r($aList,1).'</pre>');
-                    _done($aList);
-                    break;;
-                    
-                case 'project':
-                    // path /api/v1/project
-
-                    $sPrjId     = isset($aUriSplit[2]) ? $aUriSplit[2] : false;
-                    $sPrjAction = isset($aUriSplit[3]) ? $aUriSplit[3] : false;
-                    $sBranch    = implode('/', array_slice($aUriSplit, 4));
-                    
-                    // $sParam4    = isset($aUriSplit[4]) ? $aUriSplit[4] : false;
-                    // $sParam5    = isset($aUriSplit[5]) ? $aUriSplit[5] : false;
-                    $sMethod    = $_SERVER['REQUEST_METHOD'];
-                    _wd('$sPrjId = '.$sPrjId);
-                    _wd('$sPrjAction = '.$sPrjAction);
-                    _wd('$sBranch = ' . $sBranch); 
-                    
-                    $oCLog = new logger();
-                    // try to init the given project
-                    try{
-                        ob_start();
-                        $oProject=new project($sPrjId);
-                        
-                        // $oProject->setProjectById($sPrjId);
-                        ob_end_clean();
-                            
-                    } catch (Exception $exc) {
-                        _quit('ERROR: project with id ['.$sPrjId.'] does not exist.', 404);
-                    }
-
-                    // get secret
-                    $aPrjCfg=$oProject->getConfig();
-                    $sProjectSecret=isset($aPrjCfg['api']['secret']) ? $aPrjCfg['api']['secret'] : false;
-                    if(!$sProjectSecret){
-                        _quit('Access denied. API access is disabled.');
-                    }
-
-                    // check authorization 
-                    _checkAuth($sProjectSecret);
-
-                    // echo "OK: request was authorized successfully.\n";
-
-                    $oProject->oUser->setUser('api');
-
-                    switch($sPrjAction){
-                        case "build":
-                            if ($sBranch){
-                                $aResult=$oProject->setBranchname($sBranch);
-                            }
-                            $sBranchname=$oProject->getBranchname();
-                            $aRepodata = $oProject->getRemoteBranches(true); // ignore cache = true
-                            if(!isset($aRepodata[$sBranchname])){
-                                _quit('ERROR: branch not found: '.$sBranchname, 404);
-                            }
-                            
-                            
-                            // echo "branch is set to ".$oProject->getBranchname()."\n";
-                            if ($sMethod==='GET'){
-                                $sNext=$oProject->getNextPhase();
-                                _done(array(
-                                    'branch'=>$sBranchname,
-                                    'phase'=>$sNext,
-                                    'repo'=>$aRepodata[$sBranchname]
-                                ));
-                            }
-                            if ($sMethod==='POST'){
-                                echo "starting build() ...";
-                                flush();
-                                echo $oProject->build();
-                            }
-                            break;;
-                        case "phases":
-                            _done($oProject->getAllPhaseInfos());
-                            break;;
-                        default:
-                            _quit('ERROR: Wrong action ['.$sApiItem.'].');
-                    }
-      
-                    break;;
-                    
-                default:
-                    _quit('ERROR: item ['.$sApiItem.'] is invalid.');
-            }
-            break;
-        default:
-            _quit('ERROR: Wrong (unsupported) api version.');
-    }
\ No newline at end of file
+_wd('request uri is ' . $_SERVER["REQUEST_URI"]);
+_wd('<pre>GET: ' . print_r($_GET, 1) . '</pre>');
+
+
+// ---------- SPLIT URL
+
+$aUriSplit = explode('/', preg_replace('/\?.*$/', '', $_SERVER["REQUEST_URI"]));
+
+array_shift($aUriSplit);
+array_shift($aUriSplit);
+_wd('<pre>$aUriSplit: ' . print_r($aUriSplit, 1) . '</pre>');
+/*
+
+/api/v1/projects/ci/build/...
+$aUriSplit: Array
+    (
+        [0] => v1
+        [1] => projects
+        [2] => ci
+        [3] => build
+    )
+ */
+$sApiVersion = isset($aUriSplit[0]) ? $aUriSplit[0] : false;
+$sApiItem = isset($aUriSplit[1]) ? $aUriSplit[1] : false;
+
+
+if (!$sApiVersion) {
+    _quit('ERROR: no param for api version was found.');
+}
+if (!$sApiItem) {
+    _quit('ERROR: no param for item was found.');
+}
+
+
+switch ($sApiVersion) {
+    case 'v1':
+        switch ($sApiItem) {
+            case 'projects':
+
+                $oProject = new project();
+                $aList = $oProject->getProjects();
+                _wd('<pre>' . print_r($aList, 1) . '</pre>');
+                _done($aList);
+                break;
+                ;
+
+            case 'project':
+                // path /api/v1/project
+
+                $sPrjId = isset($aUriSplit[2]) ? $aUriSplit[2] : false;
+                $sPrjAction = isset($aUriSplit[3]) ? $aUriSplit[3] : false;
+                $sBranch = implode('/', array_slice($aUriSplit, 4));
+
+                // $sParam4    = isset($aUriSplit[4]) ? $aUriSplit[4] : false;
+                // $sParam5    = isset($aUriSplit[5]) ? $aUriSplit[5] : false;
+                $sMethod = $_SERVER['REQUEST_METHOD'];
+                _wd('$sPrjId = ' . $sPrjId);
+                _wd('$sPrjAction = ' . $sPrjAction);
+                _wd('$sBranch = ' . $sBranch);
+
+                $oCLog = new logger();
+                // try to init the given project
+                try {
+                    ob_start();
+                    $oProject = new project($sPrjId);
+
+                    // $oProject->setProjectById($sPrjId);
+                    ob_end_clean();
+
+                } catch (Exception $exc) {
+                    _quit('ERROR: project with id [' . $sPrjId . '] does not exist.', 404);
+                }
+
+                // get secret
+                $aPrjCfg = $oProject->getConfig();
+                $sProjectSecret = isset($aPrjCfg['api']['secret']) ? $aPrjCfg['api']['secret'] : false;
+                if (!$sProjectSecret) {
+                    _quit('Access denied. API access is disabled.');
+                }
+
+                // check authorization 
+                _checkAuth($sProjectSecret);
+
+                // echo "OK: request was authorized successfully.\n";
+
+                $oProject->oUser->setUser('api');
+
+                switch ($sPrjAction) {
+                    case "build":
+                        if ($sBranch) {
+                            $aResult = $oProject->setBranchname($sBranch);
+                        }
+                        $sBranchname = $oProject->getBranchname();
+                        $aRepodata = $oProject->getRemoteBranches(true); // ignore cache = true
+                        if (!isset($aRepodata[$sBranchname])) {
+                            _quit('ERROR: branch not found: ' . $sBranchname, 404);
+                        }
+
+
+                        // echo "branch is set to ".$oProject->getBranchname()."\n";
+                        if ($sMethod === 'GET') {
+                            $sNext = $oProject->getNextPhase();
+                            _done([
+                                'branch' => $sBranchname,
+                                'phase' => $sNext,
+                                'repo' => $aRepodata[$sBranchname]
+                            ]);
+                        }
+                        if ($sMethod === 'POST') {
+                            echo "starting build() ...";
+                            flush();
+                            echo $oProject->build();
+                        }
+                        break;
+                        ;
+                    case "phases":
+                        _done($oProject->getAllPhaseInfos());
+                        break;
+                        ;
+                    default:
+                        _quit('ERROR: Wrong action [' . $sApiItem . '].');
+                }
+
+                break;
+                ;
+
+            default:
+                _quit('ERROR: item [' . $sApiItem . '] is invalid.');
+        }
+        break;
+    default:
+        _quit('ERROR: Wrong (unsupported) api version.');
+}
\ No newline at end of file