API Documentation
Use this guide to connect external Laravel platforms to the Session Handler using dynamic platform registration, manifest fetching, record pulling, webhook receiving, realtime dashboard monitoring, Laravel Scheduler, and queue-based background processing.
Session Handler Receiver Endpoint
This endpoint is used by external platforms for realtime sending. Use POST for newly created records and PATCH for updated records.
Required Headers for Webhook Sending
External platforms must include these headers when pushing data to the Session Handler.
Accept: application/json
Content-Type: application/json
X-API-KEY: SESSION_HANDLER_GENERATED_API_KEY
ngrok-skip-browser-warning: true
platform_name.
Latest System Updates
These are the current important updates applied to the Session Handler dashboard and API workflow.
Dashboard browser AJAX now only refreshes display/status data through
GET /dashboard/realtime.
Browser JavaScript must not automatically POST Pull All Existing Records every few seconds.
Pull All Existing Records now runs only when the user manually clicks the button or when Laravel Scheduler starts it server-side.
Heavy pulling is handled using Laravel queue jobs so the dashboard does not reload or freeze.
Reverb can be disabled safely. When disabled, AJAX polling fallback will update the dashboard every 10 seconds.
For deployment, queue workers and scheduler/cron must be configured so background jobs actually finish.
Dashboard Realtime Polling Endpoint
This endpoint is used by the dashboard frontend to quietly refresh stats, platform status, synced records, logs, latest sync, and pull progress.
GET https://www.session-handler.bmwaresd.com/dashboard/realtime
Headers:
Accept: application/json
X-Requested-With: XMLHttpRequest
Manual Pull All Existing Records
This endpoint is triggered only when the user manually clicks the Pull All Existing Records button. It queues a background job instead of running the whole pull directly in browser JavaScript.
POST https://www.session-handler.bmwaresd.com/dashboard/pull-all-existing-records
Required Blade form:
<form method="POST"
action="https://www.session-handler.bmwaresd.com/dashboard/pull-all-existing-records"
data-ajax-form="pull-all-records">
<button type="button">
Pull All Existing Records
</button>
</form>
409 Conflict if another pull is already running.
This is normal protection against duplicate heavy pull jobs.
Required AJAX Setup for Dashboard Actions
All AJAX POST requests from the dashboard must include the CSRF token, same-origin credentials, and JSON response handling.
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
const response = await fetch('/dashboard/pull-all-existing-records', {
method: 'POST',
headers: {
Accept: 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': csrfToken,
},
credentials: 'same-origin',
body: new FormData(form),
});
const data = await response.json();
<meta name="csrf-token" content="pexnNTAHJ5fiOGoUdGrTe75SU5IHP4SO4FHh53OD">.
Browser Polling Rule
The browser must only poll dashboard display data. It must not start heavy pull operations automatically.
Correct browser behavior:
GET /dashboard/realtime every 10 seconds
Wrong browser behavior:
POST /dashboard/pull-all-existing-records every 10 seconds
POST /dashboard/auto-sync every few seconds
location.reload() after AJAX
Auto Sync Status Endpoint
This endpoint should be status-only. It must not execute heavy pull logic from the browser.
POST https://www.session-handler.bmwaresd.com/dashboard/auto-sync
Expected behavior:
{
"success": true,
"status": "idle",
"message": "Browser auto-sync is disabled. Automatic pulling is handled by Laravel Scheduler and queue jobs."
}
Laravel Scheduler and Queue Setup
Automatic pulling must be handled server-side using Laravel Scheduler and queue jobs.
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('session-handler:auto-pull-existing-records')
->everyMinute()
->withoutOverlapping();
withoutOverlapping() prevents the scheduler from starting another automatic pull while one is already running.
Local Herd Testing Setup
Use this setup when testing in Laravel Herd using http://session-handler.test.
APP_URL=http://session-handler.test
ASSET_URL=
SESSION_DRIVER=file
SESSION_DOMAIN=null
SESSION_SECURE_COOKIE=false
SESSION_SAME_SITE=lax
QUEUE_CONNECTION=sync
BROADCAST_CONNECTION=log
VITE_ENABLE_REVERB=false
QUEUE_CONNECTION=sync for local testing.
Production / Online Deployment Setup
Use this setup when deploying online with queue worker and scheduler support.
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com
ASSET_URL=
SESSION_DRIVER=file
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
QUEUE_CONNECTION=database
CACHE_STORE=file
BROADCAST_CONNECTION=log
VITE_ENABLE_REVERB=false
QUEUE_CONNECTION=database is used,
a queue worker must run on the server.
Required Deployment Commands
Run these after uploading changes, editing CSS/JS, changing environment values, or deploying to a server.
composer install --optimize-autoloader --no-dev
npm run build
php artisan migrate --force
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
Queue Worker Command
Required when QUEUE_CONNECTION=database. Without this, Pull All jobs will stay queued forever.
php artisan queue:work --tries=1 --timeout=900
Scheduler Command
Required for automatic server-side Pull All Existing Records.
php artisan schedule:work
* * * * * php artisan schedule:run.
Dynamic Registration Flow
This is the correct process for registering another platform using the plus button.
Send the external platform integration kit or required API instructions to your teammate.
They add the ping, manifest, records, and optional search endpoints to their Laravel platform.
In Session Handler, click the plus button and input their Platform Base API URL and Source Platform API Key.
Click Test Connection or Fetch Platform Data to verify the platform and load manifest data.
Select the modules/data you want to receive, then register the platform.
Copy the generated Session Handler API key and give it back to the external platform for webhook sending.
Use Pull All Existing Records manually or allow Laravel Scheduler to pull records server-side.
External Platform Ping Endpoint
This endpoint is used by the Session Handler to test if an external platform is active and reachable.
GET {SOURCE_BASE_API_URL}/api/session-handler/ping
Headers:
Accept: application/json
X-PLATFORM-API-KEY: SOURCE_PLATFORM_API_KEY
ngrok-skip-browser-warning: true
Expected response:
{
"success": true,
"message": "Platform is online.",
"platform_name": "PWD-CS Platform"
}
External Platform Manifest Endpoint
This endpoint must exist on the external platform. The Session Handler uses it to fetch platform name, title, modules/tabs, record types, and fields.
GET {SOURCE_BASE_API_URL}/api/session-handler/manifest
Headers:
Accept: application/json
X-PLATFORM-API-KEY: SOURCE_PLATFORM_API_KEY
ngrok-skip-browser-warning: true
External Platform Records Endpoint
This endpoint is used by the Session Handler to pull old/existing records from a selected module.
GET {SOURCE_BASE_API_URL}/api/session-handler/records/{record_type}
Example:
GET https://pwd-platform.ngrok-free.dev/api/session-handler/records/pwd_record
External Platform Search Endpoint
This optional endpoint allows the Session Handler to search external platform data by keyword or person context.
GET {SOURCE_BASE_API_URL}/api/session-handler/search?query=juan
Headers:
Accept: application/json
X-PLATFORM-API-KEY: SOURCE_PLATFORM_API_KEY
ngrok-skip-browser-warning: true
Sample Manifest Response
This is what the external platform should return from its manifest endpoint. These fields become the dynamic table headers in Session Handler.
{
"success": true,
"platform_name": "PWD-CS Platform",
"platform_title": "PWD-CS Management System",
"platform_description": "Platform for managing PWD and Senior Citizen records.",
"modules": [
{
"module_name": "PWD Records",
"record_type": "pwd_record",
"description": "PWD registration records",
"fields": [
{
"key": "pwd_number",
"label": "PWD Number",
"type": "string",
"required": true
},
{
"key": "first_name",
"label": "First Name",
"type": "string",
"required": true
},
{
"key": "middle_name",
"label": "Middle Name",
"type": "string",
"required": false
},
{
"key": "last_name",
"label": "Last Name",
"type": "string",
"required": true
},
{
"key": "suffix",
"label": "Suffix",
"type": "string",
"required": false
},
{
"key": "barangay",
"label": "Barangay",
"type": "string",
"required": false
},
{
"key": "address",
"label": "Address",
"type": "string",
"required": false
},
{
"key": "contact_number",
"label": "Contact Number",
"type": "string",
"required": false
}
]
},
{
"module_name": "Senior Citizens",
"record_type": "senior_citizen_record",
"description": "Senior citizen registration records",
"fields": [
{
"key": "senior_number",
"label": "Senior Citizen Number",
"type": "string",
"required": true
},
{
"key": "first_name",
"label": "First Name",
"type": "string",
"required": true
},
{
"key": "last_name",
"label": "Last Name",
"type": "string",
"required": true
}
]
}
]
}
Sample Old Records Response
This is what the external platform should return when Session Handler pulls existing records.
{
"success": true,
"platform_name": "PWD-CS Platform",
"module_name": "PWD Records",
"record_type": "pwd_record",
"total": 1,
"records": [
{
"reference_number": "PWD-001",
"full_name": "Juan Santos Dela Cruz",
"data": {
"pwd_number": "PWD-001",
"first_name": "Juan",
"middle_name": "Santos",
"last_name": "Dela Cruz",
"suffix": null,
"barangay": "San Juan",
"address": "Purok 1, San Juan",
"contact_number": "09123456789"
}
}
]
}
POST New Record
External platforms use POST after creating or registering a new record.
{
"module_name": "PWD Records",
"record_type": "pwd_record",
"reference_number": "PWD-001",
"full_name": "Juan Santos Dela Cruz",
"data": {
"pwd_number": "PWD-001",
"first_name": "Juan",
"middle_name": "Santos",
"last_name": "Dela Cruz",
"suffix": null,
"barangay": "San Juan",
"address": "Purok 1, San Juan",
"contact_number": "09123456789"
}
}
PATCH Updated Record
External platforms use PATCH after updating an existing record.
{
"module_name": "PWD Records",
"record_type": "pwd_record",
"reference_number": "PWD-001",
"full_name": "Juan Santos Dela Cruz",
"data": {
"barangay": "San Pedro",
"contact_number": "09991234567"
}
}
Sample Laravel Sender Service Usage
Use this in the external Laravel platform after creating or updating a record.
use App\Services\SessionHandlerWebhookService;
// After create/store
SessionHandlerWebhookService::sendCreated(
moduleName: 'PWD Records',
recordType: 'pwd_record',
data: $pwd->toArray(),
fullName: trim($pwd->first_name . ' ' . $pwd->middle_name . ' ' . $pwd->last_name),
referenceNumber: $pwd->pwd_number
);
// After update
SessionHandlerWebhookService::sendUpdated(
moduleName: 'PWD Records',
recordType: 'pwd_record',
data: $pwd->fresh()->toArray(),
fullName: trim($pwd->first_name . ' ' . $pwd->middle_name . ' ' . $pwd->last_name),
referenceNumber: $pwd->pwd_number
);
Webhook Success Response
Returned when the Session Handler successfully receives data.
{
"success": true,
"message": "New record received from PWD-CS Platform.",
"method": "POST",
"platform_name": "PWD-CS Platform",
"module_name": "PWD Records",
"record_id": 1
}
Webhook Error Response
Returned when the API key is invalid, the platform is inactive, or the module is not registered.
{
"success": false,
"message": "API key is missing, invalid, or platform is inactive."
}
Common Troubleshooting
Use these checks if the dashboard, API connection, or Pull All process behaves abnormally.
CSRF token mismatch. Make sure the layout has the CSRF meta tag, AJAX sends
X-CSRF-TOKEN, and local HTTP uses SESSION_SECURE_COOKIE=false.
Pull All is already running. Clear stuck cache or wait for the existing job to finish.
If using database queue, make sure php artisan queue:work is running.
If the UI looks different without npm run dev, run npm run build,
clear Laravel cache, and make sure ASSET_URL= is blank for local Herd.
If /dashboard/realtime appears every second, check for duplicate polling,
old cached JavaScript, or Reverb events triggering unthrottled refreshes.
If background pull never ends, the queue worker is probably not running or a cache lock is stuck.
Registered Platforms and API Keys
Give the generated Session Handler API key to the correct external platform. This key is used for POST and PATCH realtime sending.
lqhA3Jy0BdI7Si98b9isujpNevOI9FOXK8zRVuHj
Registered Modules and Fields
Resident Records resident
Blotter Records blotter
Health Assessments health_assessment
Daily Health Maintenance daily_health
Certificate Issuances certificate_issuance
Barangay Physical Info barangay_physical_info
Official Records official
Fiscal Records fiscal_record
Awards award
Socio Facilities socio_facility
Socio Properties socio_property
Socio Water socio_water
Gwi7rnGKQdkw5VLnHuNWT8qmk5qFgkzKlbOm877T
Registered Modules and Fields
Patient Records patient
Appointment Records appointment
Visiting Records visiting_record
Laboratory Records laboratory_record
Prescription Records prescription
Billing Records billing
Clinical Abstracts clinical_abstract
jUIuQwfDxF2CCWkeluShhDxs5xKJgbmZw1449FrF
Registered Modules and Fields
Appointment Requests appointment_request
Doctor Records doctor
Doctor Schedules doctor_schedule
RWsAytIvK0WvkzcpbKdE7ZLHBW6MeuNPESND7fLJ
Registered Modules and Fields
PWD Records pwd_record
Senior Citizens senior_citizen_record
k7ebpWnxN5ivDMFupp76hnYiaa75LTeBB94FCocM