Howto:Store PBX CDRs on a Synology NAS locally using HTTP (Post)
Applies To
This information applies to:
- innovaphone PBX with CDR generation
- innovaphone CDR1 interface
- Synology NAS with DSM 7
- Synology Web Station
- PHP 8.2 or similar
More Information
This Howto explains how to store innovaphone PBX Call Detail Records (CDRs) on a Synology NAS.
The PBX sends the CDR data using HTTP POST to a small PHP receiver running on Synology Web Station.
The receiver stores multiple CDR entries inside the same log file.
When the current log file reaches the configured maximum size, a new log file is created automatically.
innovaphone PBX
|
| HTTP POST
v
Synology Web Station
|
| receiver.php
v
/web/cdr/logs/
|
+-- cdr_2026-09-17_12-30-00.log
+-- cdr_2026-09-17_14-15-22.log
+-- ...
Problem Details
The innovaphone PBX can generate CDR information for completed calls.
If the CDR information should be stored on an external Synology NAS, a small HTTP receiver can be used.
The PBX sends every CDR to the receiver.
The receiver:
- receives the CDR using HTTP POST
- adds the CDR to the current log file
- creates a new file when the configured maximum size is reached
- uses the date and time in the log filename
This avoids creating one file for every individual CDR.
System Requirements
The following components are required:
- innovaphone PBX
- CDR generation enabled
- Synology NAS
- Synology Web Station
- PHP 8.2 or similar
- network connectivity between the PBX and the Synology NAS
In this Howto the following example values are used:
Synology IP: 192.168.10.50
HTTP Port: 49173
Receiver: /receiver.php
These are only example values.
Replace 192.168.10.50 with the actual IP address of the Synology NAS.
The port can also be changed. It is recommended to use a high dedicated port instead of a common HTTP port.
Installation
Install Web Station and PHP
Open the Synology Package Center.
Install:
- Web Station
- PHP 8.2
After installation, open Web Station.
Create the CDR folders
Open Synology File Station.
Inside the web shared folder create:
/web/cdr/
/web/cdr/logs/
The folder structure should look like:
web
└── cdr
├── receiver.php
└── logs
Configure permissions
The PHP web server must have permission to create and modify files inside the logs folder.
Open:
File Station
/web/cdr/logs
Properties
Permission
The Synology system user http must have Read & Write permission.
Apply the permission to:
This folder, sub-folders and files

If the http user has only Read permission, the PHP receiver can receive the request but cannot save the CDR.
The receiver may return:
500 Internal Server Error
Could not save CDR
Create receiver.php
Create a php file and place it in:
/web/cdr/receiver.php
Insert the following code:
<?php
/*
* innovaphone CDR receiver for Synology
*
* What this script does:
* 1. Receives a CDR sent by the PBX with HTTP POST.
* 2. Saves the received CDR inside a log file.
* 3. Keeps adding new CDRs to the same file.
* 4. When the file becomes too large, it creates a new log file.
*/
$logDir = __DIR__ . "/logs";
/*
* Maximum size of one log file.
* 1024 * 1024 = 1 MB.
*
* Example for 10 MB:
* $maxSize = 10 * 1024 * 1024;
*/
$maxSize = 1024 * 1024;
/*
* This small file remembers which CDR log file is currently active.
*/
$stateFile = $logDir . "/current.txt";
/*
* This file prevents two CDRs from being written
* at exactly the same time.
*/
$lockFile = $logDir . "/.cdr.lock";
/*
* Read the CDR data sent by the innovaphone PBX.
*/
$data = file_get_contents("php://input");
/*
* Stop if no CDR data was received.
*/
if (empty($data)) {
http_response_code(400);
echo "No CDR data received";
exit;
}
/*
* Lock the storage while a CDR is being written.
*/
$lock = fopen($lockFile, "c");
if (!$lock || !flock($lock, LOCK_EX)) {
http_response_code(500);
echo "Could not lock CDR storage";
exit;
}
/*
* Read the name of the current log file.
*/
$currentName = "";
if (file_exists($stateFile)) {
$currentName = trim(file_get_contents($stateFile));
}
/*
* Build the full path of the current log file.
*/
$currentFile = $currentName !== ""
? $logDir . "/" . $currentName
: "";
/*
* Create a new log file when:
* - no active file exists
* - the active file was deleted
* - the maximum file size would be exceeded
*/
if (
$currentFile === "" ||
!file_exists($currentFile) ||
filesize($currentFile) + strlen($data) > $maxSize
) {
/*
* Create the filename using the current date and time.
*
* Example:
* cdr_2026-09-17_12-30-00.log
*/
$currentName = "cdr_" . date("Y-m-d_H-i-s") . ".log";
$currentFile = $logDir . "/" . $currentName;
/*
* Add a unique value if the filename already exists.
*/
if (file_exists($currentFile)) {
$currentName =
"cdr_" .
date("Y-m-d_H-i-s") .
"_" .
uniqid() .
".log";
$currentFile = $logDir . "/" . $currentName;
}
/*
* Remember which log file is currently active.
*/
file_put_contents($stateFile, $currentName);
}
/*
* Add the new CDR to the end of the current log file.
* Existing CDRs are not overwritten.
*/
$result = file_put_contents(
$currentFile,
$data . PHP_EOL,
FILE_APPEND
);
/*
* Release the lock.
*/
flock($lock, LOCK_UN);
fclose($lock);
/*
* Return an error if the CDR could not be saved.
*/
if ($result === false) {
http_response_code(500);
echo "Could not save CDR";
exit;
}
/*
* Confirm that the CDR was successfully received and saved.
*/
http_response_code(200);
echo "OK";
?>
Example log files:
cdr_2026-09-17_12-30-00.log
cdr_2026-09-17_14-15-22.log
The default maximum file size is 1 MB.
Configuration
Create the PHP Web Service
Open:
Web Station
Web Service
Create
Create a PHP web service.
Example:
Name: receiver_cdr
PHP: PHP 8.2
Document root: /web/cdr
Save the configuration.
The service status should show Normal.

Create the Web Portal
Open:
Web Station
Web Portal
Create
Select the previously created CDR Web Service.
Configure:
Portal type: Port-based
HTTP: Enabled
Port: 49173
A high dedicated port is used in this example instead of a common HTTP port.

The receiver URL will look similar to:
http://192.168.10.50:49173/receiver.php
Replace the IP address and, if required, the port with the values used in the actual installation.
Test the PHP receiver
Before configuring the PBX, test the receiver manually.
From Windows Command Prompt:
curl.exe -i -X POST -H "Content-Type: text/xml" --data-binary "<cdr><test>Hello</test></cdr>" "http://192.168.10.50:49173/receiver.php"
The expected answer is:
HTTP/1.1 200 OK
OK

Check:
/web/cdr/logs/
A log file should have been created.
Enable CDR generation
Open:
PBX
General
Enable:
Generate CDRs
Configure CDR1
Open:
Gateway
CDR1
Configure:
Type: HTTP
Address: 192.168.10.50
Port: 49173
Method: POST
Path: /receiver.php
Replace the example IP address with the actual Synology IP address.

Save the configuration.
The PBX must be able to reach:
<SYNOLOGY_IP>:<CDR_PORT>
For example:
192.168.10.50:49173
Test with a real call
Make a short call through the PBX:
Call
Answer
Hang up
Then check:
/web/cdr/logs/
The current log file should contain the CDR information generated by the PBX.

Change the maximum log file size
The default maximum size is 1 MB.
You will see at first a file named "cdr_current.xml" once it reaches the limit set, it will save the cdr acumulated, and then it will keep on saving cdrs on "cdr_current.xml".
If you want to increase the maximum size go inside receiver.php:
$maxSize = 1024 * 1024;
For 10 MB:
$maxSize = 10 * 1024 * 1024;
Old log files are not deleted automatically.
Known Problems
HTTP is not encrypted
The setup described in this Howto uses HTTP.
The CDR information is therefore transmitted without encryption.
This configuration should only be used on a trusted internal network.
No authentication
The PHP receiver does not require a username or password.
A high dedicated port such as 49173 makes the service less obvious than using a common web port, but it must not be considered a security mechanism.
If possible, configure the Synology firewall so that the CDR port can only be accessed from the IP address of the innovaphone PBX.
Log files are not deleted automatically
The receiver creates new files when the configured maximum size is reached.
Old files remain on the NAS.
Storage usage should therefore be monitored.
HTTP 500 - Could not save CDR
Check:
/web/cdr/logs/
The Synology system user http must have Read & Write permission.