TimeOffice Biometric API — Integration Setup Guide

Follow the steps below to configure and deploy the integration for a new client.

What This Script Does

1

Configure the Script

Open timeoffice-api.php and update the values inside the Config block at the top of the file.

1.1 — TimeOffice API Credentials

$corporateId = "corporateId";  // Client's Corporate ID from TimeOffice
$username    = "username";     // API username provided by TimeOffice
$password    = "password";     // API password provided by TimeOffice
These three values are provided by the client or the TimeOffice account admin.
They are automatically combined and Base64-encoded to form the Authorization header in this format:
CorporateID:Username:Password:true

1.2 — Database Credentials

$serverName   = 'localhost';  // MSSQL server hostname or IP
$uid          = '';           // Database username
$pwd          = '';           // Database password
$databaseName = '';           // Target database name
Use the client's MSSQL connection details. The script uses the sqlsrv PHP driver.
2

Verify the Target Table

Ensure the biometric_punches table exists in the target database with at least the following columns:

Column Type Notes
emp_codeVARCHAREmployee code from TimeOffice
log_dateDATEDate portion of the punch (YYYY-MM-DD)
punch_timeTIMETime portion of the punch (HH:MM:SS)
device_serial_numberVARCHARHardcoded as TIMEOFFICE001
device_nameVARCHARHardcoded as TimeOffice
log_date_timeDATETIMEFull punch timestamp
created_dateDATETIMERow insertion timestamp
3

Deploy Files to Apache

Copy the integration files into your Apache web root. The script needs to be accessible via a URL so the cron job can trigger it using wget.

3.1 — Copy the Files

On the same server as Apache, run:

cp -r /source/path/biometric-timeoffice /var/www/html/biometric-timeoffice

If deploying from a remote machine, use scp:

scp -r ./biometric-timeoffice user@your-server-ip:/var/www/html/biometric-timeoffice

3.2 — Set Folder Permissions

The script writes timeoffice_state.json to its own directory. Apache's user (usually www-data) must have write permission on that folder:

# Give Apache write access to the folder
chown -R www-data:www-data /var/www/html/biometric-timeoffice
chmod -R 755 /var/www/html/biometric-timeoffice
Without write permission, the state file cannot be saved and the script will re-pull all data on every run, causing duplicate inserts.

3.3 — Verify the URL is Accessible

Open a browser or run the following to confirm Apache serves the script correctly:

curl -I http://your-domain.com/biometric-timeoffice/timeoffice-api.php

You should receive an HTTP/1.1 200 OK response. If you get a 403 or 404, check the folder path and Apache permissions.

4

Set Up the Cron Job

Open the crontab editor on the server:

crontab -e

4.1 — Trigger via wget (Recommended for Apache)

Since the script is hosted on Apache, use wget to hit the URL every 5 minutes:

*/5 * * * * wget -q -O /var/log/timeoffice.log http://your-domain.com/biometric-timeoffice/timeoffice-api.php 2>&1
-q suppresses wget's own download progress output.
-O /var/log/timeoffice.log writes the script's output (inserted count, errors) to a log file.
Replace your-domain.com with your actual domain or server IP.

4.2 — Alternative: Trigger via PHP CLI

If you prefer not to use a public URL, you can still trigger it directly via PHP CLI:

*/5 * * * * php /var/www/html/biometric-timeoffice/timeoffice-api.php >> /var/log/timeoffice.log 2>&1
Both approaches produce identical results. The wget method is preferred when running on Apache as it goes through the same execution environment as a normal web request.
5

First Run

On the first run there is no state file yet. The script will default to pulling from the start of the current month. Trigger it manually once to verify everything is working:

wget -q -O - http://your-domain.com/biometric-timeoffice/timeoffice-api.php

Expected output on success:

State updated — next LastRecord: 032026$489
Done. Inserted: 150 | Failed: 0

Troubleshooting

  • DB Connection failed. Check the database credentials in Step 1.2
  • API returned error: ... Check the API credentials in Step 1.1
  • cURL Error: ... Check network or firewall access to api.etimeoffice.com
  • HTTP 403 / 404 Check Apache folder path and file permissions (Step 3.2 & 3.3)
  • State file not updating Apache user lacks write permission on the folder — re-run Step 3.2

State File

The file timeoffice_state.json is created automatically after the first successful run in the same directory as the script. It looks like:

{
    "last_record": "032026$489"
}
Do not delete this file once the integration is live. Deleting it will cause the next run to re-pull from the start of the current month, resulting in duplicate inserts.
If you need to re-sync from a specific point, edit last_record manually using the format MMYYYY$LastID — for example, 012026$1 to re-pull from January 2026.

Pre-Go-Live Checklist

  • Set $corporateId, $username, $password from the client's TimeOffice account
  • Set $serverName, $uid, $pwd, $databaseName for the client's MSSQL database
  • Confirm biometric_punches table exists with the correct columns
  • Copy files to /var/www/html/biometric-timeoffice/ on the Apache server
  • Set folder ownership and permissions (chown / chmod)
  • Verify the script URL returns HTTP 200
  • Run the script manually via wget and confirm records are inserted
  • Add the cron job with the wget entry